AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
Spell Class Reference

#include "Spell.h"

Classes

struct  GOTargetInfo
 
struct  HitTriggerSpell
 
struct  ItemTargetInfo
 

Public Types

typedef std::set< Aura * > UsedSpellMods
 

Public Member Functions

 Spell (Unit *caster, SpellInfo const *info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID=ObjectGuid::Empty, bool skipCheck=false)
 
 ~Spell ()
 
void EffectNULL (SpellEffIndex effIndex)
 
void EffectUnused (SpellEffIndex effIndex)
 
void EffectDistract (SpellEffIndex effIndex)
 
void EffectPull (SpellEffIndex effIndex)
 
void EffectSchoolDMG (SpellEffIndex effIndex)
 
void EffectEnvironmentalDMG (SpellEffIndex effIndex)
 
void EffectInstaKill (SpellEffIndex effIndex)
 
void EffectDummy (SpellEffIndex effIndex)
 
void EffectTeleportUnits (SpellEffIndex effIndex)
 
void EffectApplyAura (SpellEffIndex effIndex)
 
void EffectSendEvent (SpellEffIndex effIndex)
 
void EffectPowerBurn (SpellEffIndex effIndex)
 
void EffectPowerDrain (SpellEffIndex effIndex)
 
void EffectHeal (SpellEffIndex effIndex)
 
void EffectBind (SpellEffIndex effIndex)
 
void EffectHealthLeech (SpellEffIndex effIndex)
 
void EffectQuestComplete (SpellEffIndex effIndex)
 
void EffectCreateItem (SpellEffIndex effIndex)
 
void EffectCreateItem2 (SpellEffIndex effIndex)
 
void EffectCreateRandomItem (SpellEffIndex effIndex)
 
void EffectPersistentAA (SpellEffIndex effIndex)
 
void EffectEnergize (SpellEffIndex effIndex)
 
void EffectOpenLock (SpellEffIndex effIndex)
 
void EffectSummonChangeItem (SpellEffIndex effIndex)
 
void EffectProficiency (SpellEffIndex effIndex)
 
void EffectApplyAreaAura (SpellEffIndex effIndex)
 
void EffectSummonType (SpellEffIndex effIndex)
 
void EffectLearnSpell (SpellEffIndex effIndex)
 
void EffectDispel (SpellEffIndex effIndex)
 
void EffectDualWield (SpellEffIndex effIndex)
 
void EffectPickPocket (SpellEffIndex effIndex)
 
void EffectAddFarsight (SpellEffIndex effIndex)
 
void EffectUntrainTalents (SpellEffIndex effIndex)
 
void EffectHealMechanical (SpellEffIndex effIndex)
 
void EffectJump (SpellEffIndex effIndex)
 
void EffectJumpDest (SpellEffIndex effIndex)
 
void EffectLeapBack (SpellEffIndex effIndex)
 
void EffectQuestClear (SpellEffIndex effIndex)
 
void EffectTeleUnitsFaceCaster (SpellEffIndex effIndex)
 
void EffectLearnSkill (SpellEffIndex effIndex)
 
void EffectAddHonor (SpellEffIndex effIndex)
 
void EffectTradeSkill (SpellEffIndex effIndex)
 
void EffectEnchantItemPerm (SpellEffIndex effIndex)
 
void EffectEnchantItemTmp (SpellEffIndex effIndex)
 
void EffectTameCreature (SpellEffIndex effIndex)
 
void EffectSummonPet (SpellEffIndex effIndex)
 
void EffectLearnPetSpell (SpellEffIndex effIndex)
 
void EffectWeaponDmg (SpellEffIndex effIndex)
 
void EffectForceCast (SpellEffIndex effIndex)
 
void EffectTriggerSpell (SpellEffIndex effIndex)
 
void EffectTriggerMissileSpell (SpellEffIndex effIndex)
 
void EffectThreat (SpellEffIndex effIndex)
 
void EffectHealMaxHealth (SpellEffIndex effIndex)
 
void EffectInterruptCast (SpellEffIndex effIndex)
 
void EffectSummonObjectWild (SpellEffIndex effIndex)
 
void EffectScriptEffect (SpellEffIndex effIndex)
 
void EffectSanctuary (SpellEffIndex effIndex)
 
void EffectAddComboPoints (SpellEffIndex effIndex)
 
void EffectDuel (SpellEffIndex effIndex)
 
void EffectStuck (SpellEffIndex effIndex)
 
void EffectSummonPlayer (SpellEffIndex effIndex)
 
void EffectActivateObject (SpellEffIndex effIndex)
 
void EffectApplyGlyph (SpellEffIndex effIndex)
 
void EffectEnchantHeldItem (SpellEffIndex effIndex)
 
void EffectSummonObject (SpellEffIndex effIndex)
 
void EffectResurrect (SpellEffIndex effIndex)
 
void EffectParry (SpellEffIndex effIndex)
 
void EffectBlock (SpellEffIndex effIndex)
 
void EffectLeap (SpellEffIndex effIndex)
 
void EffectTransmitted (SpellEffIndex effIndex)
 
void EffectDisEnchant (SpellEffIndex effIndex)
 
void EffectInebriate (SpellEffIndex effIndex)
 
void EffectFeedPet (SpellEffIndex effIndex)
 
void EffectDismissPet (SpellEffIndex effIndex)
 
void EffectReputation (SpellEffIndex effIndex)
 
void EffectForceDeselect (SpellEffIndex effIndex)
 
void EffectSelfResurrect (SpellEffIndex effIndex)
 
void EffectSkinning (SpellEffIndex effIndex)
 
void EffectCharge (SpellEffIndex effIndex)
 
void EffectChargeDest (SpellEffIndex effIndex)
 
void EffectProspecting (SpellEffIndex effIndex)
 
void EffectMilling (SpellEffIndex effIndex)
 
void EffectRenamePet (SpellEffIndex effIndex)
 
void EffectSendTaxi (SpellEffIndex effIndex)
 
void EffectSummonCritter (SpellEffIndex effIndex)
 
void EffectKnockBack (SpellEffIndex effIndex)
 
void EffectPullTowards (SpellEffIndex effIndex)
 
void EffectDispelMechanic (SpellEffIndex effIndex)
 
void EffectResurrectPet (SpellEffIndex effIndex)
 
void EffectDestroyAllTotems (SpellEffIndex effIndex)
 
void EffectDurabilityDamage (SpellEffIndex effIndex)
 
void EffectSkill (SpellEffIndex effIndex)
 
void EffectTaunt (SpellEffIndex effIndex)
 
void EffectDurabilityDamagePCT (SpellEffIndex effIndex)
 
void EffectModifyThreatPercent (SpellEffIndex effIndex)
 
void EffectResurrectNew (SpellEffIndex effIndex)
 
void EffectAddExtraAttacks (SpellEffIndex effIndex)
 
void EffectSpiritHeal (SpellEffIndex effIndex)
 
void EffectSkinPlayerCorpse (SpellEffIndex effIndex)
 
void EffectStealBeneficialBuff (SpellEffIndex effIndex)
 
void EffectUnlearnSpecialization (SpellEffIndex effIndex)
 
void EffectHealPct (SpellEffIndex effIndex)
 
void EffectEnergizePct (SpellEffIndex effIndex)
 
void EffectTriggerRitualOfSummoning (SpellEffIndex effIndex)
 
void EffectSummonRaFFriend (SpellEffIndex effIndex)
 
void EffectKillCreditPersonal (SpellEffIndex effIndex)
 
void EffectKillCredit (SpellEffIndex effIndex)
 
void EffectQuestFail (SpellEffIndex effIndex)
 
void EffectQuestStart (SpellEffIndex effIndex)
 
void EffectRedirectThreat (SpellEffIndex effIndex)
 
void EffectGameObjectDamage (SpellEffIndex effIndex)
 
void EffectGameObjectRepair (SpellEffIndex effIndex)
 
void EffectGameObjectSetDestructionState (SpellEffIndex effIndex)
 
void EffectActivateRune (SpellEffIndex effIndex)
 
void EffectCreateTamedPet (SpellEffIndex effIndex)
 
void EffectDiscoverTaxi (SpellEffIndex effIndex)
 
void EffectTitanGrip (SpellEffIndex effIndex)
 
void EffectEnchantItemPrismatic (SpellEffIndex effIndex)
 
void EffectPlayMusic (SpellEffIndex effIndex)
 
void EffectSpecCount (SpellEffIndex effIndex)
 
void EffectActivateSpec (SpellEffIndex effIndex)
 
void EffectPlaySound (SpellEffIndex effIndex)
 
void EffectRemoveAura (SpellEffIndex effIndex)
 
void EffectCastButtons (SpellEffIndex effIndex)
 
void EffectRechargeManaGem (SpellEffIndex effIndex)
 
void InitExplicitTargets (SpellCastTargets const &targets)
 
void SelectExplicitTargets ()
 
void SelectSpellTargets ()
 
void SelectEffectImplicitTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 &processedEffectMask)
 
void SelectImplicitChannelTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitNearbyTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitConeTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitAreaTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitCasterDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitDestDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitCasterObjectTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetObjectTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitChainTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
 
void SelectImplicitTrajTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectEffectTypeImplicitTargets (uint8 effIndex)
 
uint32 GetSearcherTypeMask (SpellTargetObjectTypes objType, ConditionList *condList)
 
template<class SEARCHER >
void SearchTargets (SEARCHER &searcher, uint32 containerMask, Unit *referer, Position const *pos, float radius)
 
WorldObjectSearchNearbyTarget (float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList=nullptr)
 
void SearchAreaTargets (std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList)
 
void SearchChainTargets (std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
 
SpellCastResult prepare (SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
 
void cancel (bool bySelf=false)
 
void update (uint32 difftime)
 
void cast (bool skipCheck=false)
 
void _cast (bool skipCheck)
 
void finish (bool ok=true)
 
void TakePower ()
 
void TakeAmmo ()
 
void TakeRunePower (bool didHit)
 
void TakeReagents ()
 
void TakeCastItem ()
 
SpellCastResult CheckCast (bool strict)
 
SpellCastResult CheckPetCast (Unit *target)
 
void handle_immediate ()
 
uint64 handle_delayed (uint64 t_offset)
 
void _handle_immediate_phase ()
 
void _handle_finish_phase ()
 
void OnSpellLaunch ()
 
SpellCastResult CheckItems ()
 
SpellCastResult CheckSpellFocus ()
 
SpellCastResult CheckRange (bool strict)
 
SpellCastResult CheckPower ()
 
SpellCastResult CheckRuneCost (uint32 RuneCostID)
 
SpellCastResult CheckCasterAuras (bool preventionOnly) const
 
int32 CalculateSpellDamage (uint8 i, Unit const *target) const
 
bool HaveTargetsForEffect (uint8 effect) const
 
void Delayed ()
 
void DelayedChannel ()
 
uint32 getState () const
 
void setState (uint32 state)
 
void DoCreateItem (uint8 effIndex, uint32 itemId)
 
void WriteSpellGoTargets (WorldPacket *data)
 Writes miss and hit targets for a SMSG_SPELL_GO packet.
 
void WriteAmmoToPacket (WorldPacket *data)
 
bool CheckEffectTarget (Unit const *target, uint32 eff) const
 
bool CanAutoCast (Unit *target)
 
void CheckSrc ()
 
void CheckDst ()
 
void SendCastResult (SpellCastResult result)
 
void SendPetCastResult (SpellCastResult result)
 
void SendSpellStart ()
 
void SendSpellGo ()
 
void SendSpellCooldown ()
 
void SendLogExecute ()
 
void ExecuteLogEffectTakeTargetPower (uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
 
void ExecuteLogEffectExtraAttacks (uint8 effIndex, Unit *victim, uint32 attCount)
 
void ExecuteLogEffectInterruptCast (uint8 effIndex, Unit *victim, uint32 spellId)
 
void ExecuteLogEffectDurabilityDamage (uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
 
void ExecuteLogEffectOpenLock (uint8 effIndex, Object *obj)
 
void ExecuteLogEffectCreateItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectDestroyItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectSummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectUnsummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectResurrect (uint8 effIndex, Unit *target)
 
void SendInterrupted (uint8 result)
 
void SendChannelUpdate (uint32 time)
 
void SendChannelStart (uint32 duration)
 
void SendResurrectRequest (Player *target)
 
void HandleEffects (Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
 
void HandleThreatSpells ()
 
void AddComboPointGain (Unit *target, int8 amount)
 
int32 GetCastTime () const
 
bool IsAutoRepeat () const
 
void SetAutoRepeat (bool rep)
 
void ReSetTimer ()
 
bool IsNextMeleeSwingSpell () const
 
bool IsTriggered () const
 
bool HasTriggeredCastFlag (TriggerCastFlags flag) const
 
bool IsChannelActive () const
 
bool IsAutoActionResetSpell () const
 
bool IsIgnoringCooldowns () const
 
bool IsDeletable () const
 
void SetReferencedFromCurrent (bool yes)
 
bool IsInterruptable () const
 
void SetExecutedCurrently (bool yes)
 
uint64 GetDelayStart () const
 
void SetDelayStart (uint64 m_time)
 
uint64 GetDelayMoment () const
 
uint64 GetDelayTrajectory () const
 
uint64 CalculateDelayMomentForDst () const
 
void RecalculateDelayMomentForDst ()
 
bool IsNeedSendToClient (bool go) const
 
CurrentSpellTypes GetCurrentContainer () const
 
UnitGetCaster () const
 
UnitGetOriginalCaster () const
 
SpellInfo const * GetSpellInfo () const
 
int32 GetPowerCost () const
 
bool UpdatePointers ()
 
void CleanupTargetList ()
 
void SetSpellValue (SpellValueMod mod, int32 value)
 
SpellValue const * GetSpellValue ()
 
void LoadScripts ()
 
std::list< TargetInfo > * GetUniqueTargetInfo ()
 
uint32 GetTriggeredByAuraTickNumber () const
 
TriggerCastFlags GetTriggeredCastFlags () const
 
SpellSchoolMask GetSpellSchoolMask () const
 

Static Public Member Functions

static void WriteCastResultInfo (WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
 
static void SendCastResult (Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
 

Public Attributes

SpellInfo const *const m_spellInfo
 
Itemm_CastItem
 
Itemm_weaponItem
 
ObjectGuid m_castItemGUID
 
uint8 m_cast_count
 
uint32 m_glyphIndex
 
uint32 m_preCastSpell
 
SpellCastTargets m_targets
 
SpellCustomErrors m_customError
 
Unitm_comboTarget
 
int8 m_comboPointGain
 
UsedSpellMods m_appliedMods
 

Protected Types

typedef std::list< HitTriggerSpellHitTriggerSpellList
 

Protected Member Functions

bool HasGlobalCooldown () const
 
void TriggerGlobalCooldown ()
 
void CancelGlobalCooldown ()
 
void SendLoot (ObjectGuid guid, LootType loottype)
 
std::string GetDebugInfo () const
 
bool isDelayableNoMore ()
 
void prepareDataForTriggerSystem (AuraEffect const *triggeredByAura)
 
void AddUnitTarget (Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
 
void AddGOTarget (GameObject *target, uint32 effectMask)
 
void AddItemTarget (Item *item, uint32 effectMask)
 
void AddDestTarget (SpellDestination const &dest, uint32 effIndex)
 
void DoAllEffectOnTarget (TargetInfo *target)
 
SpellMissInfo DoSpellHitOnUnit (Unit *unit, uint32 effectMask, bool scaleAura)
 
void DoTriggersOnSpellHit (Unit *unit, uint8 effMask)
 
void DoAllEffectOnTarget (GOTargetInfo *target)
 
void DoAllEffectOnTarget (ItemTargetInfo *target)
 
bool UpdateChanneledTargetList ()
 
bool IsValidDeadOrAliveTarget (Unit const *target) const
 
void HandleLaunchPhase ()
 
void DoAllEffectOnLaunchTarget (TargetInfo &targetInfo, float *multiplier)
 
void PrepareTargetProcessing ()
 
void FinishTargetProcessing ()
 
void InitEffectExecuteData (uint8 effIndex)
 
void CheckEffectExecuteData ()
 
void CallScriptBeforeCastHandlers ()
 
void CallScriptOnCastHandlers ()
 
void CallScriptAfterCastHandlers ()
 
SpellCastResult CallScriptCheckCastHandlers ()
 
void PrepareScriptHitHandlers ()
 
bool CallScriptEffectHandlers (SpellEffIndex effIndex, SpellEffectHandleMode mode)
 
void CallScriptBeforeHitHandlers (SpellMissInfo missInfo)
 
void CallScriptOnHitHandlers ()
 
void CallScriptAfterHitHandlers ()
 
void CallScriptObjectAreaTargetSelectHandlers (std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void CallScriptObjectTargetSelectHandlers (WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void CallScriptDestinationTargetSelectHandlers (SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
bool CheckScriptEffectImplicitTargets (uint32 effIndex, uint32 effIndexToCheck)
 
bool CanExecuteTriggersOnHit (uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
 
void PrepareTriggersExecutedOnHit ()
 
void SummonGuardian (uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
 
void CalculateJumpSpeeds (uint8 i, float dist, float &speedxy, float &speedz)
 
SpellCastResult CanOpenLock (uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
 

Protected Attributes

Unit *const m_caster
 
SpellValue *const m_spellValue
 
ObjectGuid m_originalCasterGUID
 
Unitm_originalCaster
 
Spell ** m_selfContainer
 
SpellSchoolMask m_spellSchoolMask
 
WeaponAttackType m_attackType
 
int32 m_powerCost
 
int32 m_casttime
 
int32 m_channeledDuration
 
bool m_canReflect
 
uint8 m_spellFlags
 
bool m_autoRepeat
 
uint8 m_runesState
 
uint8 m_delayAtDamageCount
 
uint64 m_delayStart
 
uint64 m_delayMoment
 
uint64 m_delayTrajectory
 
bool m_immediateHandled
 
bool m_referencedFromCurrentSpell
 
bool m_executedCurrently
 
bool m_needComboPoints
 
uint8 m_applyMultiplierMask
 
float m_damageMultipliers [3]
 
UnitunitTarget
 
ItemitemTarget
 
GameObjectgameObjTarget
 
WorldLocationdestTarget
 
int32 damage
 
SpellEffectHandleMode effectHandleMode
 
Auram_spellAura
 
DiminishingLevels m_diminishLevel
 
DiminishingGroup m_diminishGroup
 
GameObjectfocusObject
 
int32 m_damage
 
int32 m_healing
 
uint32 m_procAttacker
 
uint32 m_procVictim
 
uint32 m_procEx
 
std::list< TargetInfom_UniqueTargetInfo
 
uint8 m_channelTargetEffectMask
 
std::list< GOTargetInfom_UniqueGOTargetInfo
 
std::list< ItemTargetInfom_UniqueItemInfo
 
SpellDestination m_destTargets [MAX_SPELL_EFFECTS]
 
bool _scriptsLoaded
 
std::list< SpellScript * > m_loadedScripts
 
HitTriggerSpellList m_hitTriggerSpells
 
uint32 m_spellState
 
int32 m_timer
 
SpellEvent_spellEvent
 
TriggerCastFlags _triggeredCastFlags
 
TriggeredByAuraSpellData m_triggeredByAuraSpell
 
bool m_skipCheck
 
uint8 m_auraScaleMask
 
std::unique_ptr< PathGeneratorm_preGeneratedPath
 
bool _spellTargetsSelected
 
ByteBufferm_effectExecuteData [MAX_SPELL_EFFECTS]
 

Friends

class SpellScript
 
void Unit::SetCurrentCastedSpell (Spell *pSpell)
 

Detailed Description

Member Typedef Documentation

◆ HitTriggerSpellList

typedef std::list<HitTriggerSpell> Spell::HitTriggerSpellList
protected

◆ UsedSpellMods

typedef std::set<Aura*> Spell::UsedSpellMods

Constructor & Destructor Documentation

◆ Spell()

Spell::Spell ( Unit caster,
SpellInfo const *  info,
TriggerCastFlags  triggerFlags,
ObjectGuid  originalCasterGUID = ObjectGuid::Empty,
bool  skipCheck = false 
)
567 :
568 m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
569 m_caster((info->HasAttribute(SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster)
571{
573 m_skipCheck = skipCheck;
574 m_selfContainer = nullptr;
576 m_executedCurrently = false;
579 m_comboTarget = nullptr;
580 m_delayStart = 0;
582
584 m_auraScaleMask = 0;
585 memset(m_damageMultipliers, 0, sizeof(m_damageMultipliers));
586
587 // Get data for type of attack
588 switch (m_spellInfo->DmgClass)
589 {
593 else
595 break;
598 break;
599 default:
600 // Wands
603 else
605 break;
606 }
607
608 m_spellSchoolMask = info->GetSchoolMask(); // Can be override for some spell (wand shoot for example)
609
611 // wand case
614 m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->Damage[0].DamageType);
615
616 if (originalCasterGUID)
617 m_originalCasterGUID = originalCasterGUID;
618 else
620
623 else
624 {
627 m_originalCaster = nullptr;
628 }
629
631 _triggeredCastFlags = triggerFlags;
632 if (info->HasAttribute(SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING))
634
635 m_CastItem = nullptr;
636
637 unitTarget = nullptr;
638 itemTarget = nullptr;
639 gameObjTarget = nullptr;
640 destTarget = nullptr;
641 damage = 0;
645 m_damage = 0;
646 m_healing = 0;
647 m_procAttacker = 0;
648 m_procVictim = 0;
649 m_procEx = 0;
650 focusObject = nullptr;
651 m_cast_count = 0;
652 m_glyphIndex = 0;
653 m_preCastSpell = 0;
654 m_spellAura = nullptr;
655 _scriptsLoaded = false;
656
657 //Auto Shot & Shoot (wand)
659
660 m_runesState = 0;
661 m_powerCost = 0; // setup to correct value in Spell::prepare, must not be used before.
662 m_casttime = 0; // setup to correct value in Spell::prepare, must not be used before.
663 m_timer = 0; // will set to castime in prepare
664 m_channeledDuration = 0; // will be setup in Spell::handle_immediate
665 m_immediateHandled = false;
666
668
670
671 // Determine if spell can be reflected back to the caster
672 // Patch 1.2 notes: Spell Reflection no longer reflects abilities
676
678 memset(m_effectExecuteData, 0, MAX_SPELL_EFFECTS * sizeof(ByteBuffer*));
679
680 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
682
683 // xinef:
684 _spellTargetsSelected = false;
685
686 m_weaponItem = nullptr;
687}
std::uint8_t uint8
Definition: Define.h:109
std::uint32_t uint32
Definition: Define.h:107
@ TYPEID_PLAYER
Definition: ObjectGuid.h:36
@ OFF_ATTACK
Definition: Unit.h:210
@ BASE_ATTACK
Definition: Unit.h:209
@ RANGED_ATTACK
Definition: Unit.h:211
@ DIMINISHING_LEVEL_1
Definition: Unit.h:263
@ SPELL_EFFECT_HANDLE_LAUNCH
Definition: Spell.h:233
@ SPELL_FLAG_NORMAL
Definition: Spell.h:81
@ SPELL_STATE_NULL
Definition: Spell.h:223
TriggerCastFlags
Definition: SpellDefines.h:130
@ TRIGGERED_CAST_DIRECTLY
Will ignore combo point requirement.
Definition: SpellDefines.h:139
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will ignore aura scaling.
Definition: SpellDefines.h:137
#define sSpellMgr
Definition: SpellMgr.h:825
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:1637
@ DIMINISHING_NONE
Definition: SharedDefines.h:3258
@ SPELL_EFFECT_DISPEL
Definition: SharedDefines.h:816
#define CLASSMASK_WAND_USERS
Definition: SharedDefines.h:174
@ SPELL_ATTR2_AUTO_REPEAT
Definition: SharedDefines.h:461
@ SPELL_ATTR1_NO_REFLECTION
Definition: SharedDefines.h:426
@ SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON
Definition: SharedDefines.h:517
@ SPELL_DAMAGE_CLASS_RANGED
Definition: SharedDefines.h:1548
@ SPELL_DAMAGE_CLASS_MAGIC
Definition: SharedDefines.h:1546
@ SPELL_DAMAGE_CLASS_MELEE
Definition: SharedDefines.h:1547
@ SPELL_CUSTOM_ERROR_NONE
Definition: SharedDefines.h:1143
@ SPELL_ATTR0_IS_ABILITY
Definition: SharedDefines.h:386
@ SPELL_ATTR0_NO_IMMUNITIES
Definition: SharedDefines.h:411
@ SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING
Definition: SharedDefines.h:537
@ SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER
Definition: SharedDefines.h:622
SpellSchoolMask
Definition: SharedDefines.h:295
Unit * GetUnit(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:202
Definition: Item.h:220
Player * ToPlayer()
Definition: Object.h:198
bool IsInWorld() const
Definition: Object.h:104
TypeID GetTypeId() const
Definition: Object.h:124
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:109
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition: PlayerStorage.cpp:511
Unit * GetCharmerOrOwner() const
Definition: Unit.h:1189
uint32 getClassMask() const
Definition: Unit.h:766
Definition: Spell.h:94
Definition: Spell.h:211
Unit * m_comboTarget
Definition: Spell.h:542
int8 m_comboPointGain
Definition: Spell.h:543
GameObject * gameObjTarget
Definition: Spell.h:653
bool m_referencedFromCurrentSpell
Definition: Spell.h:644
bool m_canReflect
Definition: Spell.h:620
uint32 m_procVictim
Definition: Spell.h:675
Unit * m_originalCaster
Definition: Spell.h:608
bool m_needComboPoints
Definition: Spell.h:646
uint64 m_delayStart
Definition: Spell.h:638
bool _scriptsLoaded
Definition: Spell.h:726
TriggerCastFlags _triggeredCastFlags
Definition: Spell.h:767
int32 damage
Definition: Spell.h:655
SpellEffectHandleMode effectHandleMode
Definition: Spell.h:656
int32 m_channeledDuration
Definition: Spell.h:619
Aura * m_spellAura
Definition: Spell.h:658
SpellDestination m_destTargets[MAX_SPELL_EFFECTS]
Definition: Spell.h:701
Unit *const m_caster
Definition: Spell.h:602
uint8 m_delayAtDamageCount
Definition: Spell.h:627
WeaponAttackType m_attackType
Definition: Spell.h:616
bool m_immediateHandled
Definition: Spell.h:641
uint32 m_spellState
Definition: Spell.h:763
ObjectGuid m_originalCasterGUID
Definition: Spell.h:606
void CleanupTargetList()
Definition: Spell.cpp:2371
int32 m_timer
Definition: Spell.h:764
int32 m_casttime
Definition: Spell.h:618
Item * itemTarget
Definition: Spell.h:652
uint8 m_cast_count
Definition: Spell.h:524
int32 m_damage
Definition: Spell.h:668
bool m_executedCurrently
Definition: Spell.h:645
DiminishingLevels m_diminishLevel
Definition: Spell.h:661
float m_damageMultipliers[3]
Definition: Spell.h:648
ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]
Definition: Spell.h:781
uint8 m_auraScaleMask
Definition: Spell.h:775
SpellCustomErrors m_customError
Definition: Spell.h:528
uint8 m_spellFlags
Definition: Spell.h:622
bool m_skipCheck
Definition: Spell.h:774
int32 m_healing
Definition: Spell.h:669
uint32 m_glyphIndex
Definition: Spell.h:525
uint8 m_channelTargetEffectMask
Definition: Spell.h:683
Item * m_weaponItem
Definition: Spell.h:522
Unit * unitTarget
Definition: Spell.h:651
SpellSchoolMask m_spellSchoolMask
Definition: Spell.h:615
SpellEvent * _spellEvent
Definition: Spell.h:766
bool _spellTargetsSelected
Definition: Spell.h:779
uint32 m_preCastSpell
Definition: Spell.h:526
WorldLocation * destTarget
Definition: Spell.h:654
Spell ** m_selfContainer
Definition: Spell.h:610
uint8 m_applyMultiplierMask
Definition: Spell.h:647
DiminishingGroup m_diminishGroup
Definition: Spell.h:662
uint32 m_procEx
Definition: Spell.h:676
Item * m_CastItem
Definition: Spell.h:521
SpellValue *const m_spellValue
Definition: Spell.h:604
int32 m_powerCost
Definition: Spell.h:617
uint32 m_procAttacker
Definition: Spell.h:674
GameObject * focusObject
Definition: Spell.h:665
SpellInfo const *const m_spellInfo
Definition: Spell.h:520
uint8 m_runesState
Definition: Spell.h:625
bool m_autoRepeat
Definition: Spell.h:624
bool IsPassive() const
Definition: SpellInfo.cpp:1097
bool NeedsComboPoints() const
Definition: SpellInfo.cpp:1265
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:415
bool HasEffect(SpellEffects effect) const
Definition: SpellInfo.cpp:875
bool IsPositive() const
Definition: SpellInfo.cpp:1236
bool IsAutoRepeatRangedSpell() const
Definition: SpellInfo.cpp:1282
uint32 DmgClass
Definition: SpellInfo.h:389
bool IsRangedWeaponSpell() const
Definition: SpellInfo.cpp:1275
Definition: ByteBuffer.h:70

References _scriptsLoaded, _spellTargetsSelected, _triggeredCastFlags, BASE_ATTACK, CLASSMASK_WAND_USERS, CleanupTargetList(), damage, destTarget, DIMINISHING_LEVEL_1, DIMINISHING_NONE, SpellInfo::DmgClass, effectHandleMode, focusObject, gameObjTarget, Unit::getClassMask(), Object::GetGUID(), SpellInfo::GetSchoolMask(), Object::GetTypeId(), ObjectAccessor::GetUnit(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellInfo::IsAutoRepeatRangedSpell(), Object::IsInWorld(), SpellInfo::IsPassive(), SpellInfo::IsPositive(), SpellInfo::IsRangedWeaponSpell(), itemTarget, m_applyMultiplierMask, m_attackType, m_auraScaleMask, m_autoRepeat, m_canReflect, m_cast_count, m_caster, m_CastItem, m_casttime, m_channeledDuration, m_channelTargetEffectMask, m_comboPointGain, m_comboTarget, m_customError, m_damage, m_damageMultipliers, m_delayAtDamageCount, m_delayStart, m_destTargets, m_diminishGroup, m_diminishLevel, m_effectExecuteData, m_executedCurrently, m_glyphIndex, m_healing, m_immediateHandled, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_powerCost, m_preCastSpell, m_procAttacker, m_procEx, m_procVictim, m_referencedFromCurrentSpell, m_runesState, m_selfContainer, m_skipCheck, m_spellAura, m_spellFlags, m_spellInfo, m_spellSchoolMask, m_spellState, m_timer, m_weaponItem, MAX_SPELL_EFFECTS, SpellInfo::NeedsComboPoints(), OFF_ATTACK, RANGED_ATTACK, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR1_NO_REFLECTION, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING, SPELL_CUSTOM_ERROR_NONE, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_FLAG_NORMAL, SPELL_STATE_NULL, Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, TYPEID_PLAYER, and unitTarget.

◆ ~Spell()

Spell::~Spell ( )
690{
691 // unload scripts
692 while (!m_loadedScripts.empty())
693 {
694 std::list<SpellScript*>::iterator itr = m_loadedScripts.begin();
695 (*itr)->_Unload();
696 delete (*itr);
697 m_loadedScripts.erase(itr);
698 }
699
701 {
702 // Clean the reference to avoid later crash.
703 // If this error is repeating, we may have to add an ASSERT to better track down how we get into this case.
704 LOG_ERROR("spells", "Spell::~Spell: deleting spell for spell ID {}. However, spell still referenced.", m_spellInfo->Id);
705 *m_selfContainer = nullptr;
706 }
707
708 delete m_spellValue;
709
711}
#define LOG_ERROR(filterType__,...)
Definition: Log.h:156
void CheckEffectExecuteData()
Definition: Spell.cpp:8476
std::list< SpellScript * > m_loadedScripts
Definition: Spell.h:741
uint32 Id
Definition: SpellInfo.h:320

References CheckEffectExecuteData(), SpellInfo::Id, LOG_ERROR, m_loadedScripts, m_referencedFromCurrentSpell, m_selfContainer, m_spellInfo, and m_spellValue.

Member Function Documentation

◆ _cast()

void Spell::_cast ( bool  skipCheck)

Not own traded item (in trader trade slot) req. reagents including triggered spell case

3800{
3801 // update pointers base at GUIDs to prevent access to non-existed already object
3802 if (!UpdatePointers())
3803 {
3804 // cancel the spell if UpdatePointers() returned false, something wrong happened there
3805 cancel();
3806 return;
3807 }
3808
3809 // cancel at lost explicit target during cast
3811 {
3812 cancel();
3813 return;
3814 }
3815
3816 // Xinef: implement attribute SPELL_ATTR1_DISMISS_PET_FIRST, on spell cast current pet is dismissed and charms are removed
3818 {
3820 if (Pet* pet = m_caster->ToPlayer()->GetPet())
3822
3823 if (Unit* charm = m_caster->GetCharm())
3824 charm->RemoveAurasByType(SPELL_AURA_MOD_CHARM, m_caster->GetGUID());
3825 }
3826
3827 if (Player* playerCaster = m_caster->ToPlayer())
3828 {
3829 // now that we've done the basic check, now run the scripts
3830 // should be done before the spell is actually executed
3831 sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
3832
3833 // As of 3.0.2 pets begin attacking their owner's target immediately
3834 // Let any pets know we've attacked something. Check DmgClass for harmful spells only
3835 // This prevents spells such as Hunter's Mark from triggering pet attack
3836 // xinef: take into account SPELL_ATTR3_SUPRESS_TARGET_PROCS
3838 if (!playerCaster->m_Controlled.empty())
3839 for (Unit::ControlSet::iterator itr = playerCaster->m_Controlled.begin(); itr != playerCaster->m_Controlled.end(); ++itr)
3840 if (Unit* pet = *itr)
3841 if (pet->IsAlive() && pet->GetTypeId() == TYPEID_UNIT)
3842 pet->ToCreature()->AI()->OwnerAttacked(m_targets.GetUnitTarget());
3843 }
3844
3846
3850
3852
3853 Player* modOwner = m_caster->GetSpellModOwner();
3854 // skip check if done already (for instant cast spells for example)
3855 if (!skipCheck)
3856 {
3857 SpellCastResult castResult = CheckCast(false);
3858 if (castResult != SPELL_CAST_OK)
3859 {
3860 SendCastResult(castResult);
3861 SendInterrupted(0);
3862
3863 finish(false);
3864 SetExecutedCurrently(false);
3865 return;
3866 }
3867
3868 // additional check after cast bar completes (must not be in CheckCast)
3869 // if trade not complete then remember it in trade data
3871 {
3873 {
3874 if (TradeData* my_trade = m_caster->ToPlayer()->GetTradeData())
3875 {
3876 if (!my_trade->IsInAcceptProcess())
3877 {
3878 // Spell will be casted at completing the trade. Silently ignore at this place
3879 my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
3881 SendInterrupted(0);
3882
3883 finish(false);
3884 SetExecutedCurrently(false);
3885 return;
3886 }
3887 }
3888 }
3889 }
3890 }
3891
3892 if (modOwner)
3893 modOwner->SetSpellModTakingSpell(this, true);
3894
3897
3898 if (modOwner)
3899 modOwner->SetSpellModTakingSpell(this, false);
3900
3901 // Spell may be finished after target map check
3903 {
3904 SendInterrupted(0);
3905 finish(false);
3906 SetExecutedCurrently(false);
3907 return;
3908 }
3909
3910 if (modOwner)
3911 modOwner->SetSpellModTakingSpell(this, true);
3912
3914
3916
3917 if (modOwner)
3918 modOwner->SetSpellModTakingSpell(this, false);
3919
3920 // traded items have trade slot instead of guid in m_itemTargetGUID
3921 // set to real guid to be sent later to the client
3923
3925 {
3927 {
3930 }
3931
3933 }
3934
3936 {
3937 // Powers have to be taken before SendSpellGo
3938 TakePower();
3939 TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
3940 }
3941 else if (Item* targetItem = m_targets.GetItemTarget())
3942 {
3944 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
3945 TakeReagents();
3946 }
3947
3949
3950 // CAST SPELL
3951 if (modOwner)
3952 modOwner->SetSpellModTakingSpell(this, true);
3953
3955
3957
3958 // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
3959 SendSpellGo();
3960
3961 if (modOwner)
3962 modOwner->SetSpellModTakingSpell(this, false);
3963
3964 if (m_originalCaster)
3965 {
3966 // Handle procs on cast
3967 uint32 procAttacker = m_procAttacker;
3968 if (!procAttacker)
3969 {
3970 bool IsPositive = m_spellInfo->IsPositive();
3972 {
3974 }
3975 else
3976 {
3978 }
3979 }
3980
3981 uint32 procEx = PROC_EX_NORMAL_HIT;
3982
3983 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3984 {
3985 if (ihit->missCondition != SPELL_MISS_NONE)
3986 {
3987 continue;
3988 }
3989
3990 if (!ihit->crit)
3991 {
3992 continue;
3993 }
3994
3995 procEx |= PROC_EX_CRITICAL_HIT;
3996 break;
3997 }
3998
4001 }
4002
4003 if (modOwner)
4004 modOwner->SetSpellModTakingSpell(this, true);
4005
4007 if (resetAttackTimers)
4008 {
4010 for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i)
4011 {
4012 if ((*i)->IsAffectedOnSpell(m_spellInfo))
4013 {
4014 resetAttackTimers = false;
4015 break;
4016 }
4017 }
4018 }
4019
4020 // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
4021 if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled())/* xinef: we dont need this || m_spellInfo->Id == 14157*/)
4022 {
4023 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4024 // in case delayed spell remove item at cast delay start
4025 TakeCastItem();
4026
4027 // Okay, maps created, now prepare flags
4028 m_immediateHandled = false;
4030 SetDelayStart(0);
4031
4034
4035 // remove all applied mods at this point
4036 // dont allow user to use them twice in case spell did not reach current target
4037 if (modOwner)
4038 modOwner->RemoveSpellMods(this);
4039
4040 // Xinef: why do we keep focus after spell is sent to air?
4041 // Xinef: Because of this, in the middle of some animation after setting targetguid to 0 etc
4042 // Xinef: we get focused to it out of nowhere...
4043 if (Creature* creatureCaster = m_caster->ToCreature())
4044 creatureCaster->ReleaseFocus(this);
4045 }
4046 else
4047 {
4048 // Immediate spell, no big deal
4050 }
4051
4052 if (resetAttackTimers)
4053 {
4054 if (m_casttime == 0 && m_spellInfo->CalcCastTime())
4055 {
4056 resetAttackTimers = false;
4057 }
4058
4059 if (resetAttackTimers)
4060 {
4062
4064 {
4066 }
4067
4069 }
4070 }
4071
4073
4074 if (modOwner)
4075 modOwner->SetSpellModTakingSpell(this, false);
4076
4077 if (const std::vector<int32>* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
4078 {
4079 for (std::vector<int32>::const_iterator i = spell_triggered->begin(); i != spell_triggered->end(); ++i)
4080 if (*i < 0)
4082 else
4084 }
4085
4086 // Interrupt Spell casting
4087 // handle this here, in other places SpellHitTarget can be set to nullptr, if there is an error in this function
4089 if (Unit* target = m_targets.GetUnitTarget())
4090 if (target->GetTypeId() == TYPEID_UNIT)
4091 m_caster->CastSpell(target, 32747, true);
4092
4093 // xinef: start combat at cast for delayed spells, only for explicit target
4094 if (Unit* target = m_targets.GetUnitTarget())
4097 m_caster->CombatStartOnCast(target, !m_spellInfo->HasAttribute(SPELL_ATTR3_SUPRESS_TARGET_PROCS), GetDelayMoment() + 500); // xinef: increase this time so we dont leave and enter combat in a moment
4098
4102
4103 SetExecutedCurrently(false);
4104}
@ TYPEID_UNIT
Definition: ObjectGuid.h:35
@ PET_SAVE_AS_CURRENT
Definition: PetDefines.h:42
@ CHEAT_COOLDOWN
Definition: Player.h:1000
@ UNIT_STATE_CASTING
Definition: UnitDefines.h:164
#define sScriptMgr
Definition: ScriptMgr.h:706
@ SPELL_AURA_MOD_CHARM
Definition: SpellAuraDefines.h:69
@ SPELL_AURA_IGNORE_MELEE_RESET
Definition: SpellAuraDefines.h:335
@ SPELL_AURA_BIND_SIGHT
Definition: SpellAuraDefines.h:64
@ SPELL_STATE_DELAYED
Definition: Spell.h:228
@ SPELL_STATE_FINISHED
Definition: Spell.h:226
@ TRIGGERED_IGNORE_POWER_AND_REAGENT_COST
Will ignore Spell and Category cooldowns.
Definition: SpellDefines.h:134
@ TRIGGERED_IGNORE_CAST_ITEM
Will ignore power and reagent cost.
Definition: SpellDefines.h:135
@ TRIGGERED_IGNORE_SET_FACING
Will ignore interruptible aura's at cast.
Definition: SpellDefines.h:141
@ TARGET_FLAG_TRADE_ITEM
Definition: SpellInfo.h:58
@ TARGET_FLAG_UNIT
Definition: SpellInfo.h:47
@ PROC_EX_CRITICAL_HIT
Definition: SpellMgr.h:195
@ PROC_EX_NORMAL_HIT
Definition: SpellMgr.h:194
@ PROC_SPELL_PHASE_CAST
Definition: SpellMgr.h:243
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS
Definition: SpellMgr.h:128
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS
Definition: SpellMgr.h:122
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG
Definition: SpellMgr.h:125
@ PROC_FLAG_NONE
Definition: SpellMgr.h:105
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG
Definition: SpellMgr.h:131
@ ACHIEVEMENT_TIMED_TYPE_ITEM
Definition: DBCEnums.h:115
@ ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM
Definition: DBCEnums.h:155
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL
Definition: DBCEnums.h:143
@ SPELL_ATTR7_CAN_CAUSE_INTERRUPT
Definition: SharedDefines.h:652
@ SPELL_EFFECT_SUMMON_PET
Definition: SharedDefines.h:834
@ SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS
Definition: SharedDefines.h:473
@ SPELL_ATTR1_DISMISS_PET_FIRST
Definition: SharedDefines.h:419
@ SPELL_ATTR3_SUPRESS_TARGET_PROCS
Definition: SharedDefines.h:510
@ SPELL_DAMAGE_CLASS_NONE
Definition: SharedDefines.h:1545
@ SPELL_MISS_NONE
Definition: SharedDefines.h:1519
SpellCastResult
Definition: SharedDefines.h:948
@ SPELL_FAILED_DONT_REPORT
Definition: SharedDefines.h:976
@ SPELL_CAST_OK
Definition: SharedDefines.h:1138
Definition: Creature.h:46
uint32 GetEntry() const
Definition: Object.h:112
Creature * ToCreature()
Definition: Object.h:200
Definition: Pet.h:41
Definition: Player.h:1063
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition: PlayerUpdates.cpp:2127
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition: Player.cpp:10033
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
Definition: Player.cpp:13867
void RemoveSpellMods(Spell *spell)
Definition: Player.cpp:9965
Pet * GetPet() const
Definition: Player.cpp:8862
bool GetCommandStatus(uint32 command) const
Definition: Player.h:1177
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition: Player.cpp:9013
TradeData * GetTradeData() const
Definition: Player.h:1367
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition: Player.cpp:3502
Definition: TradeData.h:36
Definition: Unit.h:630
void ClearUnitState(uint32 f)
Definition: Unit.h:739
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1309
Unit * GetCharm() const
Definition: Unit.cpp:10593
Player * GetSpellModOwner() const
Definition: Unit.cpp:16492
void CombatStartOnCast(Unit *target, bool initialAggro=true, uint32 duration=0)
Definition: Unit.cpp:13623
bool haveOffhandWeapon() const
Definition: Unit.cpp:522
bool IsPet() const
Definition: Unit.h:753
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition: Unit.cpp:4058
SpellCastResult CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition: Unit.cpp:1151
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4865
static void ProcDamageAndSpell(Unit *actor, Unit *victim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType=BASE_ATTACK, SpellInfo const *procSpellInfo=nullptr, SpellInfo const *procAura=nullptr, int8 procAuraEffectIndex=-1, Spell const *procSpell=nullptr, DamageInfo *damageInfo=nullptr, HealInfo *healInfo=nullptr, uint32 procPhase=2)
Definition: Unit.cpp:6323
bool HasUnitState(const uint32 f) const
Definition: Unit.h:738
bool IsFriendlyTo(Unit const *unit) const
Definition: Unit.cpp:10177
bool IsControlledByPlayer() const
Definition: Unit.h:1170
std::list< AuraEffect * > AuraEffectList
Definition: Unit.h:646
void SetInFront(WorldObject const *target)
Definition: Unit.cpp:20411
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition: Unit.cpp:643
WorldObject * GetObjectTarget() const
Definition: Spell.cpp:311
void UpdateTradeSlotItem()
Definition: Spell.cpp:348
ObjectGuid GetObjectTargetGUID() const
Definition: Spell.cpp:316
Item * GetItemTarget() const
Definition: Spell.h:139
uint32 GetTargetMask() const
Definition: Spell.h:117
Unit * GetUnitTarget() const
Definition: Spell.cpp:232
int8 effectIndex
Definition: Spell.h:279
SpellInfo const * spellInfo
Definition: Spell.h:278
SpellInfo const * GetSpellInfo() const
Definition: Spell.h:575
void CallScriptAfterCastHandlers()
Definition: Spell.cpp:8530
void PrepareTriggersExecutedOnHit()
Definition: Spell.cpp:8736
bool HasTriggeredCastFlag(TriggerCastFlags flag) const
Definition: Spell.h:553
SpellCastTargets m_targets
Definition: Spell.h:527
TriggeredByAuraSpellData m_triggeredByAuraSpell
Definition: Spell.h:772
void handle_immediate()
Definition: Spell.cpp:4106
void SendSpellGo()
Definition: Spell.cpp:4783
void TakeReagents()
Definition: Spell.cpp:5517
void SetExecutedCurrently(bool yes)
Definition: Spell.h:561
void SendInterrupted(uint8 result)
Definition: Spell.cpp:5160
void PrepareScriptHitHandlers()
Definition: Spell.cpp:8562
void CallScriptOnCastHandlers()
Definition: Spell.cpp:8517
void cancel(bool bySelf=false)
Definition: Spell.cpp:3710
void SendSpellCooldown()
Definition: Spell.cpp:4346
void CallScriptBeforeCastHandlers()
Definition: Spell.cpp:8504
void HandleLaunchPhase()
Definition: Spell.cpp:8217
bool UpdatePointers()
Definition: Spell.cpp:7847
void SetDelayStart(uint64 m_time)
Definition: Spell.h:563
std::list< TargetInfo > m_UniqueTargetInfo
Definition: Spell.h:682
void SelectSpellTargets()
Definition: Spell.cpp:815
void TakePower()
Definition: Spell.cpp:5301
SpellCastResult CheckCast(bool strict)
Definition: Spell.cpp:5639
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition: Spell.cpp:4655
uint64 GetDelayMoment() const
Definition: Spell.h:564
void TakeCastItem()
Definition: Spell.cpp:5238
bool IsAutoActionResetSpell() const
Definition: Spell.cpp:8061
void finish(bool ok=true)
Definition: Spell.cpp:4473
float Speed
Definition: SpellInfo.h:370
bool IsChanneled() const
Definition: SpellInfo.cpp:1255
uint32 CalcCastTime(Unit *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2351
bool HasAura(AuraType aura) const
Definition: SpellInfo.cpp:892

References _spellTargetsSelected, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, ACHIEVEMENT_TIMED_TYPE_ITEM, BASE_ATTACK, SpellInfo::CalcCastTime(), CallScriptAfterCastHandlers(), CallScriptBeforeCastHandlers(), CallScriptOnCastHandlers(), cancel(), Unit::CastSpell(), CHEAT_COOLDOWN, CheckCast(), Unit::ClearUnitState(), Unit::CombatStartOnCast(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, finish(), Unit::GetAuraEffectsByType(), Unit::GetCharm(), Player::GetCommandStatus(), GetDelayMoment(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetObjectTargetGUID(), Player::GetPet(), GetSpellInfo(), Unit::GetSpellModOwner(), SpellCastTargets::GetTargetMask(), Player::GetTradeData(), Object::GetTypeId(), SpellCastTargets::GetUnitTarget(), handle_immediate(), HandleLaunchPhase(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), SpellInfo::HasEffect(), HasTriggeredCastFlag(), Unit::HasUnitState(), Unit::haveOffhandWeapon(), SpellInfo::Id, IsAutoActionResetSpell(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), Unit::IsFriendlyTo(), Unit::IsNonMeleeSpellCast(), Unit::IsPet(), SpellInfo::IsPositive(), m_caster, m_CastItem, m_casttime, m_immediateHandled, m_originalCaster, m_procAttacker, m_spellInfo, m_spellState, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, OFF_ATTACK, PET_SAVE_AS_CURRENT, PrepareScriptHitHandlers(), PrepareTriggersExecutedOnHit(), PROC_EX_CRITICAL_HIT, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_NONE, PROC_SPELL_PHASE_CAST, Unit::ProcDamageAndSpell(), RANGED_ATTACK, Unit::RemoveAurasDueToSpell(), Player::RemovePet(), Player::RemoveSpellCooldown(), Player::RemoveSpellMods(), Unit::resetAttackTimer(), SelectSpellTargets(), SendCastResult(), SendInterrupted(), SendSpellCooldown(), SendSpellGo(), SetDelayStart(), SetExecutedCurrently(), Unit::SetInFront(), Player::SetSpellModTakingSpell(), SpellInfo::Speed, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_AURA_BIND_SIGHT, SPELL_AURA_IGNORE_MELEE_RESET, SPELL_AURA_MOD_CHARM, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_SUMMON_PET, SPELL_FAILED_DONT_REPORT, SPELL_MISS_NONE, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, TriggeredByAuraSpellData::spellInfo, sScriptMgr, sSpellMgr, Player::StartTimedAchievement(), TakeCastItem(), TakePower(), TakeReagents(), TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_IGNORE_CAST_ITEM, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SET_FACING, TYPEID_PLAYER, TYPEID_UNIT, UNIT_STATE_CASTING, Player::UpdateAchievementCriteria(), UpdatePointers(), and SpellCastTargets::UpdateTradeSlotItem().

Referenced by cast().

◆ _handle_finish_phase()

void Spell::_handle_finish_phase ( )
4272{
4273 // Take for real after all targets are processed
4275 {
4277 }
4278
4279 // Real add combo points from effects
4281 {
4282 // remove Premed-like effects unless they were caused by ourselves
4283 // (this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore!)
4285 {
4287 }
4288
4290 }
4291
4293 {
4295 }
4296
4299 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4300 {
4301 // Xinef: Properly clear infinite cooldowns in some cases
4302 if (ihit->targetGUID == m_caster->GetGUID() && ihit->missCondition != SPELL_MISS_NONE)
4305 }
4306
4307 // Handle procs on finish
4308 if (m_originalCaster)
4309 {
4310 uint32 procAttacker = m_procAttacker;
4311 if (!procAttacker)
4312 {
4313 bool IsPositive = m_spellInfo->IsPositive();
4315 {
4317 }
4318 else
4319 {
4321 }
4322 }
4323
4324 uint32 procEx = PROC_EX_NORMAL_HIT;
4325 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4326 {
4327 if (ihit->missCondition != SPELL_MISS_NONE)
4328 {
4329 continue;
4330 }
4331
4332 if (!ihit->crit)
4333 {
4334 continue;
4335 }
4336
4337 procEx |= PROC_EX_CRITICAL_HIT;
4338 break;
4339 }
4340
4343 }
4344}
@ SPELL_AURA_RETAIN_COMBO_POINTS
Definition: SpellAuraDefines.h:211
@ PROC_SPELL_PHASE_FINISH
Definition: SpellMgr.h:245
@ SPELL_EFFECT_ADD_EXTRA_ATTACKS
Definition: SharedDefines.h:797
void SendCooldownEvent(SpellInfo const *spellInfo, uint32 itemId=0, Spell *spell=nullptr, bool setCooldown=true)
Definition: Player.cpp:11061
void SetLastExtraAttackSpell(uint32 spellId)
Definition: Unit.h:913
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition: Unit.cpp:10543
void ClearComboPoints()
Definition: Unit.cpp:16779
void AddComboPoints(Unit *target, int8 count)
Definition: Unit.cpp:16753
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition: Unit.cpp:5055
bool IsAutoRepeat() const
Definition: Spell.h:548
bool IsNextMeleeSwingSpell() const
Definition: Spell.cpp:8051
bool IsCooldownStartedOnEvent() const
Definition: SpellInfo.cpp:1211

References Unit::AddComboPoints(), BASE_ATTACK, Unit::ClearComboPoints(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetGUID(), Object::GetTypeId(), SpellInfo::HasAura(), SpellInfo::HasEffect(), SpellInfo::Id, IsAutoRepeat(), SpellInfo::IsCooldownStartedOnEvent(), IsNextMeleeSwingSpell(), SpellInfo::IsPositive(), m_caster, m_comboPointGain, m_comboTarget, m_needComboPoints, m_originalCaster, m_procAttacker, m_spellInfo, m_triggeredByAuraSpell, m_UniqueTargetInfo, PROC_EX_CRITICAL_HIT, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_NONE, PROC_SPELL_PHASE_FINISH, Unit::ProcDamageAndSpell(), Unit::RemoveAurasByType(), Player::SendCooldownEvent(), Unit::SetLastExtraAttackSpell(), SPELL_AURA_RETAIN_COMBO_POINTS, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_ADD_EXTRA_ATTACKS, SPELL_MISS_NONE, TriggeredByAuraSpellData::spellInfo, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by handle_delayed(), and handle_immediate().

◆ _handle_immediate_phase()

void Spell::_handle_immediate_phase ( )
4244{
4245 m_spellAura = nullptr;
4246 // initialize Diminishing Returns Data
4249
4250 // handle some immediate features of the spell here
4252
4254
4255 // handle effects with SPELL_EFFECT_HANDLE_HIT mode
4256 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4257 {
4258 // don't do anything for empty effect
4259 if (!m_spellInfo->Effects[j].IsEffect())
4260 continue;
4261
4262 // call effect handlers to handle destination hit
4263 HandleEffects(nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT);
4264 }
4265
4266 // process items
4267 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
4268 DoAllEffectOnTarget(&(*ihit));
4269}
@ SPELL_EFFECT_HANDLE_HIT
Definition: Spell.h:235
void HandleThreatSpells()
Definition: Spell.cpp:5566
void HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
Definition: Spell.cpp:5613
std::list< ItemTargetInfo > m_UniqueItemInfo
Definition: Spell.h:699
void DoAllEffectOnTarget(TargetInfo *target)
Definition: Spell.cpp:2609
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition: SpellInfo.h:393

References DIMINISHING_LEVEL_1, DIMINISHING_NONE, DoAllEffectOnTarget(), SpellInfo::Effects, HandleEffects(), HandleThreatSpells(), m_diminishGroup, m_diminishLevel, m_spellAura, m_spellInfo, m_UniqueItemInfo, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), and SPELL_EFFECT_HANDLE_HIT.

Referenced by handle_delayed(), and handle_immediate().

◆ AddComboPointGain()

void Spell::AddComboPointGain ( Unit target,
int8  amount 
)
inline
531 {
532 if (target != m_comboTarget)
533 {
534 m_comboTarget = target;
535 m_comboPointGain = amount;
536 }
537 else
538 {
539 m_comboPointGain += amount;
540 }
541 }

References m_comboPointGain, and m_comboTarget.

Referenced by EffectAddComboPoints(), and EffectWeaponDmg().

◆ AddDestTarget()

void Spell::AddDestTarget ( SpellDestination const &  dest,
uint32  effIndex 
)
protected
2605{
2606 m_destTargets[effIndex] = dest;
2607}

References m_destTargets.

Referenced by SelectSpellTargets().

◆ AddGOTarget()

void Spell::AddGOTarget ( GameObject target,
uint32  effectMask 
)
protected
2514{
2515 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2516 {
2517 if (!m_spellInfo->Effects[effIndex].IsEffect())
2518 effectMask &= ~(1 << effIndex);
2519 else
2520 {
2521 switch (m_spellInfo->Effects[effIndex].Effect)
2522 {
2526 if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
2527 effectMask &= ~(1 << effIndex);
2528 break;
2529 default:
2530 break;
2531 }
2532 }
2533 }
2534
2535 if (!effectMask)
2536 return;
2537
2538 ObjectGuid targetGUID = go->GetGUID();
2539
2540 // Lookup target in already in list
2541 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
2542 {
2543 if (targetGUID == ihit->targetGUID) // Found in list
2544 {
2545 ihit->effectMask |= effectMask; // Add only effect mask
2546 return;
2547 }
2548 }
2549
2550 // This is new target calculate data for him
2551
2552 GOTargetInfo target;
2553 target.targetGUID = targetGUID;
2554 target.effectMask = effectMask;
2555 target.processed = false; // Effects not apply on target
2556
2557 // Spell have speed - need calculate incoming time
2558 if (m_spellInfo->Speed > 0.0f)
2559 {
2560 // calculate spell incoming interval
2561 float dist = m_caster->GetDistance(go->GetPositionX(), go->GetPositionY(), go->GetPositionZ());
2562 if (dist < 5.0f)
2563 dist = 5.0f;
2564 target.timeDelay = uint64(floor(dist / m_spellInfo->Speed * 1000.0f));
2565 if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
2566 m_delayMoment = target.timeDelay;
2567 }
2568 else
2569 target.timeDelay = 0LL;
2570
2571 // Add target to list
2572 m_UniqueGOTargetInfo.push_back(target);
2573}
std::uint64_t uint64
Definition: Define.h:106
@ GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
Definition: SharedDefines.h:1593
@ SPELL_EFFECT_GAMEOBJECT_REPAIR
Definition: SharedDefines.h:866
@ SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE
Definition: SharedDefines.h:867
@ SPELL_EFFECT_GAMEOBJECT_DAMAGE
Definition: SharedDefines.h:865
float GetDistance(WorldObject const *obj) const
Definition: Object.cpp:1245
Definition: ObjectGuid.h:118
uint64 m_delayMoment
Definition: Spell.h:639
std::list< GOTargetInfo > m_UniqueGOTargetInfo
Definition: Spell.h:692

References Spell::GOTargetInfo::effectMask, SpellInfo::Effects, GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING, WorldObject::GetDistance(), GameObject::GetGoType(), Object::GetGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), m_caster, m_delayMoment, m_spellInfo, m_UniqueGOTargetInfo, MAX_SPELL_EFFECTS, Spell::GOTargetInfo::processed, SpellInfo::Speed, SPELL_EFFECT_GAMEOBJECT_DAMAGE, SPELL_EFFECT_GAMEOBJECT_REPAIR, SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE, Spell::GOTargetInfo::targetGUID, and Spell::GOTargetInfo::timeDelay.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitConeTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ AddItemTarget()

void Spell::AddItemTarget ( Item item,
uint32  effectMask 
)
protected
2576{
2577 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2578 if (!m_spellInfo->Effects[effIndex].IsEffect())
2579 effectMask &= ~(1 << effIndex);
2580
2581 // no effects left
2582 if (!effectMask)
2583 return;
2584
2585 // Lookup target in already in list
2586 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
2587 {
2588 if (item == ihit->item) // Found in list
2589 {
2590 ihit->effectMask |= effectMask; // Add only effect mask
2591 return;
2592 }
2593 }
2594
2595 // This is new target add data
2596
2597 ItemTargetInfo target;
2598 target.item = item;
2599 target.effectMask = effectMask;
2600
2601 m_UniqueItemInfo.push_back(target);
2602}

References Spell::ItemTargetInfo::effectMask, SpellInfo::Effects, Spell::ItemTargetInfo::item, m_spellInfo, m_UniqueItemInfo, and MAX_SPELL_EFFECTS.

Referenced by SelectEffectTypeImplicitTargets(), and SelectImplicitTargetObjectTargets().

◆ AddUnitTarget()

void Spell::AddUnitTarget ( Unit target,
uint32  effectMask,
bool  checkIfValid = true,
bool  implicit = true 
)
protected
Todo:
: this is a hack
Todo:
: seduction should be casted only on humanoids (not demons)
2381{
2382 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2383 if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex))
2384 effectMask &= ~(1 << effIndex);
2385
2386 // no effects left
2387 if (!effectMask)
2388 return;
2389
2390 if (checkIfValid)
2391 {
2392 SpellCastResult res = m_spellInfo->CheckTarget(m_caster, target, implicit);
2393 if (res != SPELL_CAST_OK)
2394 return;
2395 }
2396
2397 // Check for effect immune skip if immuned
2398 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2399 if (target->IsImmunedToSpellEffect(m_spellInfo, effIndex))
2400 effectMask &= ~(1 << effIndex);
2401
2402 ObjectGuid targetGUID = target->GetGUID();
2403
2404 // Lookup target in already in list
2405 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2406 {
2407 if (targetGUID == ihit->targetGUID) // Found in list
2408 {
2409 ihit->effectMask |= effectMask; // Immune effects removed from mask
2410 ihit->scaleAura = false;
2411 if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask && m_caster != target)
2412 {
2413 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2414 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2415 ihit->scaleAura = true;
2416 }
2417
2418 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, *ihit);
2419 return;
2420 }
2421 }
2422
2423 // This is new target calculate data for him
2424
2425 // Get spell hit result on target
2426 TargetInfo targetInfo;
2427 targetInfo.targetGUID = targetGUID; // Store target GUID
2428 targetInfo.effectMask = effectMask; // Store all effects not immune
2429 targetInfo.processed = false; // Effects not apply on target
2430 targetInfo.alive = target->IsAlive();
2431 targetInfo.damage = 0;
2432 targetInfo.crit = false;
2433 targetInfo.scaleAura = false;
2434 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target)
2435 {
2436 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2437 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2438 targetInfo.scaleAura = true;
2439 }
2440
2441 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, targetInfo);
2442
2443 // Calculate hit result
2444 if (m_originalCaster)
2445 {
2446 targetInfo.missCondition = m_originalCaster->SpellHitResult(target, this, m_canReflect);
2447 if (m_skipCheck && targetInfo.missCondition != SPELL_MISS_IMMUNE)
2448 {
2449 targetInfo.missCondition = SPELL_MISS_NONE;
2450 }
2451 }
2452 else
2453 targetInfo.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
2454
2455 // Spell have speed - need calculate incoming time
2456 // Incoming time is zero for self casts. At least I think so.
2457 if (m_spellInfo->Speed > 0.0f && m_caster != target)
2458 {
2459 // calculate spell incoming interval
2461 float dist = m_caster->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
2462
2463 if (dist < 5.0f)
2464 dist = 5.0f;
2465 targetInfo.timeDelay = (uint64) floor(dist / m_spellInfo->Speed * 1000.0f);
2466
2467 // Calculate minimum incoming time
2468 if (m_delayMoment == 0 || m_delayMoment > targetInfo.timeDelay)
2469 m_delayMoment = targetInfo.timeDelay;
2470 }
2471 else
2472 targetInfo.timeDelay = 0LL;
2473
2474 // If target reflect spell back to caster
2475 if (targetInfo.missCondition == SPELL_MISS_REFLECT)
2476 {
2477 // Calculate reflected spell result on caster
2479
2480 if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
2481 targetInfo.reflectResult = SPELL_MISS_PARRY;
2482
2483 // Increase time interval for reflected spells by 1.5
2485 targetInfo.timeDelay += targetInfo.timeDelay >> 1;
2486
2488
2489 // HACK: workaround check for succubus seduction case
2491 if (m_caster->IsPet())
2492 {
2493 CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(m_caster->GetEntry());
2494 switch (ci->family)
2495 {
2497 {
2498 if (m_spellInfo->SpellIconID != 694) // Soothing Kiss
2499 cancel();
2500 }
2501 break;
2502 return;
2503 }
2504 }
2505 }
2506 else
2507 targetInfo.reflectResult = SPELL_MISS_NONE;
2508
2509 // Add target to list
2510 m_UniqueTargetInfo.push_back(targetInfo);
2511}
#define sObjectMgr
Definition: ObjectMgr.h:1623
@ SPELL_FLAG_REFLECTED
Definition: Spell.h:82
@ CREATURE_FAMILY_SUCCUBUS
Definition: SharedDefines.h:2664
@ SPELL_MISS_PARRY
Definition: SharedDefines.h:1523
@ SPELL_MISS_IMMUNE
Definition: SharedDefines.h:1526
@ SPELL_MISS_EVADE
Definition: SharedDefines.h:1525
@ SPELL_MISS_REFLECT
Definition: SharedDefines.h:1530
void AddEvent(BasicEvent *Event, uint64 e_time, bool set_addtime=true)
Definition: EventProcessor.h:103
uint64 CalculateTime(uint64 t_offset) const
Definition: EventProcessor.cpp:159
Definition: CreatureData.h:189
uint32 family
Definition: CreatureData.h:220
float GetPositionZ() const
Definition: Position.h:119
float GetPositionX() const
Definition: Position.h:117
float GetPositionY() const
Definition: Position.h:118
bool IsAlive() const
Definition: Unit.h:1150
SpellMissInfo SpellHitResult(Unit *victim, SpellInfo const *spell, bool canReflect=false)
Definition: Unit.cpp:3430
EventProcessor m_Events
Definition: Unit.h:1436
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, uint32 index) const
Definition: Unit.cpp:12928
uint8 GetLevel() const
Definition: Unit.h:758
Definition: Spell.h:254
bool processed
Definition: Spell.h:260
int32 damage
Definition: Spell.h:264
SpellMissInfo missCondition
Definition: Spell.h:257
bool scaleAura
Definition: Spell.h:263
bool crit
Definition: Spell.h:262
uint64 timeDelay
Definition: Spell.h:256
ObjectGuid targetGUID
Definition: Spell.h:255
SpellMissInfo reflectResult
Definition: Spell.h:258
bool alive
Definition: Spell.h:261
uint8 effectMask
Definition: Spell.h:259
bool CheckEffectTarget(Unit const *target, uint32 eff) const
Definition: Spell.cpp:7909
Definition: Spell.h:846
Definition: SpellInfo.h:316
uint32 SpellLevel
Definition: SpellInfo.h:360
SpellInfo const * GetFirstRankSpell() const
Definition: SpellInfo.cpp:2500
uint32 SpellIconID
Definition: SpellInfo.h:380
SpellCastResult CheckTarget(Unit const *caster, WorldObject const *target, bool implicit=true) const
Definition: SpellInfo.cpp:1758

References EventProcessor::AddEvent(), TargetInfo::alive, EventProcessor::CalculateTime(), cancel(), CheckEffectTarget(), SpellInfo::CheckTarget(), CREATURE_FAMILY_SUCCUBUS, TargetInfo::crit, TargetInfo::damage, TargetInfo::effectMask, SpellInfo::Effects, CreatureTemplate::family, WorldObject::GetDistance(), Object::GetEntry(), SpellInfo::GetFirstRankSpell(), Object::GetGUID(), Unit::GetLevel(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Unit::IsImmunedToSpellEffect(), Unit::IsPet(), m_auraScaleMask, m_canReflect, m_caster, m_delayMoment, Unit::m_Events, m_originalCaster, m_skipCheck, m_spellFlags, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, TargetInfo::processed, TargetInfo::reflectResult, TargetInfo::scaleAura, sObjectMgr, SpellInfo::Speed, SPELL_CAST_OK, SPELL_FLAG_REFLECTED, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, Unit::SpellHitResult(), SpellInfo::SpellIconID, SpellInfo::SpellLevel, sScriptMgr, TargetInfo::targetGUID, and TargetInfo::timeDelay.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ CalculateDelayMomentForDst()

uint64 Spell::CalculateDelayMomentForDst ( ) const
896{
897 if (m_targets.HasDst())
898 {
899 if (m_targets.HasTraj())
900 {
901 float speed = m_targets.GetSpeedXY();
902 if (speed > 0.0f)
903 return (uint64)floor(m_targets.GetDist2d() / speed * 1000.0f);
904 }
905 else if (m_spellInfo->Speed > 0.0f)
906 {
907 // We should not subtract caster size from dist calculation (fixes execution time desync with animation on client, eg. Malleable Goo cast by PP)
908 float dist = m_caster->GetExactDist(*m_targets.GetDstPos());
909 return (uint64)std::floor(dist / m_spellInfo->Speed * 1000.0f);
910 }
911 }
912
913 return 0;
914}
float GetExactDist(float x, float y, float z) const
Definition: Position.h:178
bool HasTraj() const
Definition: Spell.h:166
bool HasDst() const
Definition: Spell.h:165
float GetSpeedXY() const
Definition: Spell.h:174
float GetDist2d() const
Definition: Spell.h:173
WorldLocation const * GetDstPos() const
Definition: Spell.cpp:401

References SpellCastTargets::GetDist2d(), SpellCastTargets::GetDstPos(), Position::GetExactDist(), SpellCastTargets::GetSpeedXY(), SpellCastTargets::HasDst(), SpellCastTargets::HasTraj(), m_caster, m_spellInfo, m_targets, and SpellInfo::Speed.

Referenced by RecalculateDelayMomentForDst(), and SelectSpellTargets().

◆ CalculateJumpSpeeds()

void Spell::CalculateJumpSpeeds ( uint8  i,
float  dist,
float &  speedxy,
float &  speedz 
)
protected
1158{
1159 if (m_spellInfo->Effects[i].MiscValue)
1160 speedZ = float(m_spellInfo->Effects[i].MiscValue) / 10;
1161 else if (m_spellInfo->Effects[i].MiscValueB)
1162 speedZ = float(m_spellInfo->Effects[i].MiscValueB) / 10;
1163 else
1164 speedZ = 10.0f;
1165 speedXY = dist * 10.0f / speedZ;
1166}

References SpellInfo::Effects, and m_spellInfo.

Referenced by EffectJump(), and EffectJumpDest().

◆ CalculateSpellDamage()

int32 Spell::CalculateSpellDamage ( uint8  i,
Unit const *  target 
) const
inline
int32 CalculateSpellDamage(Unit const *target, SpellInfo const *spellProto, uint8 effect_index, int32 const *basePoints=nullptr) const
Definition: Unit.cpp:14765
int32 EffectBasePoints[MAX_SPELL_EFFECTS]
Definition: Spell.h:213

References Unit::CalculateSpellDamage(), SpellValue::EffectBasePoints, m_caster, m_spellInfo, and m_spellValue.

Referenced by CheckCast(), CheckEffectTarget(), EffectWeaponDmg(), and HandleEffects().

◆ CallScriptAfterCastHandlers()

void Spell::CallScriptAfterCastHandlers ( )
protected
8531{
8532 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8533 {
8534 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_CAST);
8535 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->AfterCast.end(), hookItr = (*scritr)->AfterCast.begin();
8536 for (; hookItr != hookItrEnd; ++hookItr)
8537 (*hookItr).Call(*scritr);
8538
8539 (*scritr)->_FinishScriptCall();
8540 }
8541}
@ SPELL_SCRIPT_HOOK_AFTER_CAST
Definition: SpellScript.h:172

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_CAST.

Referenced by _cast().

◆ CallScriptAfterHitHandlers()

void Spell::CallScriptAfterHitHandlers ( )
protected
8643{
8644 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8645 {
8646 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_HIT);
8647 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->AfterHit.end(), hookItr = (*scritr)->AfterHit.begin();
8648 for (; hookItr != hookItrEnd; ++hookItr)
8649 (*hookItr).Call(*scritr);
8650
8651 (*scritr)->_FinishScriptCall();
8652 }
8653}
@ SPELL_SCRIPT_HOOK_AFTER_HIT
Definition: SpellScript.h:165

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_HIT.

Referenced by DoAllEffectOnTarget().

◆ CallScriptBeforeCastHandlers()

void Spell::CallScriptBeforeCastHandlers ( )
protected
8505{
8506 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8507 {
8508 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_CAST);
8509 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->BeforeCast.end(), hookItr = (*scritr)->BeforeCast.begin();
8510 for (; hookItr != hookItrEnd; ++hookItr)
8511 (*hookItr).Call(*scritr);
8512
8513 (*scritr)->_FinishScriptCall();
8514 }
8515}
@ SPELL_SCRIPT_HOOK_BEFORE_CAST
Definition: SpellScript.h:170

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_CAST.

Referenced by _cast().

◆ CallScriptBeforeHitHandlers()

void Spell::CallScriptBeforeHitHandlers ( SpellMissInfo  missInfo)
protected
8617{
8618 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8619 {
8620 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
8621 std::list<SpellScript::BeforeHitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
8622 for (; hookItr != hookItrEnd; ++hookItr)
8623 (*hookItr).Call(*scritr, missInfo);
8624
8625 (*scritr)->_FinishScriptCall();
8626 }
8627}
@ SPELL_SCRIPT_HOOK_BEFORE_HIT
Definition: SpellScript.h:163

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_HIT.

Referenced by DoAllEffectOnTarget().

◆ CallScriptCheckCastHandlers()

SpellCastResult Spell::CallScriptCheckCastHandlers ( )
protected
8544{
8546 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8547 {
8548 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CHECK_CAST);
8549 std::list<SpellScript::CheckCastHandler>::iterator hookItrEnd = (*scritr)->OnCheckCast.end(), hookItr = (*scritr)->OnCheckCast.begin();
8550 for (; hookItr != hookItrEnd; ++hookItr)
8551 {
8552 SpellCastResult tempResult = (*hookItr).Call(*scritr);
8553 if (retVal == SPELL_CAST_OK)
8554 retVal = tempResult;
8555 }
8556
8557 (*scritr)->_FinishScriptCall();
8558 }
8559 return retVal;
8560}
@ SPELL_SCRIPT_HOOK_CHECK_CAST
Definition: SpellScript.h:169

References m_loadedScripts, SPELL_CAST_OK, and SPELL_SCRIPT_HOOK_CHECK_CAST.

Referenced by CheckCast().

◆ CallScriptDestinationTargetSelectHandlers()

void Spell::CallScriptDestinationTargetSelectHandlers ( SpellDestination target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8684{
8685 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8686 {
8687 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
8688 std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
8689 for (; hookItr != hookItrEnd; ++hookItr)
8690 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8691 hookItr->Call(*scritr, target);
8692
8693 (*scritr)->_FinishScriptCall();
8694 }
8695}
@ SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT
Definition: SpellScript.h:168

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT.

Referenced by SelectImplicitCasterDestTargets(), SelectImplicitDestDestTargets(), SelectImplicitTargetDestTargets(), and SelectImplicitTrajTargets().

◆ CallScriptEffectHandlers()

bool Spell::CallScriptEffectHandlers ( SpellEffIndex  effIndex,
SpellEffectHandleMode  mode 
)
protected
8569{
8570 // execute script effect handler hooks and check if effects was prevented
8571 bool preventDefault = false;
8572 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8573 {
8574 std::list<SpellScript::EffectHandler>::iterator effItr, effEndItr;
8575 SpellScriptHookType hookType;
8576 switch (mode)
8577 {
8579 effItr = (*scritr)->OnEffectLaunch.begin();
8580 effEndItr = (*scritr)->OnEffectLaunch.end();
8582 break;
8584 effItr = (*scritr)->OnEffectLaunchTarget.begin();
8585 effEndItr = (*scritr)->OnEffectLaunchTarget.end();
8587 break;
8589 effItr = (*scritr)->OnEffectHit.begin();
8590 effEndItr = (*scritr)->OnEffectHit.end();
8592 break;
8594 effItr = (*scritr)->OnEffectHitTarget.begin();
8595 effEndItr = (*scritr)->OnEffectHitTarget.end();
8597 break;
8598 default:
8599 ABORT();
8600 return false;
8601 }
8602 (*scritr)->_PrepareScriptCall(hookType);
8603 for (; effItr != effEndItr; ++effItr)
8604 // effect execution can be prevented
8605 if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex))
8606 (*effItr).Call(*scritr, effIndex);
8607
8608 if (!preventDefault)
8609 preventDefault = (*scritr)->_IsDefaultEffectPrevented(effIndex);
8610
8611 (*scritr)->_FinishScriptCall();
8612 }
8613 return preventDefault;
8614}
#define ABORT
Definition: Errors.h:76
@ SPELL_EFFECT_HANDLE_LAUNCH_TARGET
Definition: Spell.h:234
@ SPELL_EFFECT_HANDLE_HIT_TARGET
Definition: Spell.h:236
SpellScriptHookType
Definition: SpellScript.h:158
@ SPELL_SCRIPT_HOOK_EFFECT_HIT
Definition: SpellScript.h:161
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH
Definition: SpellScript.h:159
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET
Definition: SpellScript.h:160
@ SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET
Definition: SpellScript.h:162

References ABORT, m_loadedScripts, m_spellInfo, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_SCRIPT_HOOK_EFFECT_HIT, SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET, SPELL_SCRIPT_HOOK_EFFECT_LAUNCH, and SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET.

Referenced by HandleEffects().

◆ CallScriptObjectAreaTargetSelectHandlers()

void Spell::CallScriptObjectAreaTargetSelectHandlers ( std::list< WorldObject * > &  targets,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8656{
8657 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8658 {
8659 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
8660 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
8661 for (; hookItr != hookItrEnd; ++hookItr)
8662 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8663 hookItr->Call(*scritr, targets);
8664
8665 (*scritr)->_FinishScriptCall();
8666 }
8667}
@ SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT
Definition: SpellScript.h:166

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT.

Referenced by SelectImplicitAreaTargets(), SelectImplicitChainTargets(), and SelectImplicitConeTargets().

◆ CallScriptObjectTargetSelectHandlers()

void Spell::CallScriptObjectTargetSelectHandlers ( WorldObject *&  target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8670{
8671 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8672 {
8673 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
8674 std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
8675 for (; hookItr != hookItrEnd; ++hookItr)
8676 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8677 hookItr->Call(*scritr, target);
8678
8679 (*scritr)->_FinishScriptCall();
8680 }
8681}
@ SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT
Definition: SpellScript.h:167

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChannelTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ CallScriptOnCastHandlers()

void Spell::CallScriptOnCastHandlers ( )
protected
8518{
8519 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8520 {
8521 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_CAST);
8522 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->OnCast.end(), hookItr = (*scritr)->OnCast.begin();
8523 for (; hookItr != hookItrEnd; ++hookItr)
8524 (*hookItr).Call(*scritr);
8525
8526 (*scritr)->_FinishScriptCall();
8527 }
8528}
@ SPELL_SCRIPT_HOOK_ON_CAST
Definition: SpellScript.h:171

References m_loadedScripts, and SPELL_SCRIPT_HOOK_ON_CAST.

Referenced by _cast().

◆ CallScriptOnHitHandlers()

void Spell::CallScriptOnHitHandlers ( )
protected
8630{
8631 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8632 {
8633 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_HIT);
8634 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->OnHit.end(), hookItr = (*scritr)->OnHit.begin();
8635 for (; hookItr != hookItrEnd; ++hookItr)
8636 (*hookItr).Call(*scritr);
8637
8638 (*scritr)->_FinishScriptCall();
8639 }
8640}
@ SPELL_SCRIPT_HOOK_HIT
Definition: SpellScript.h:164

References m_loadedScripts, and SPELL_SCRIPT_HOOK_HIT.

Referenced by DoAllEffectOnTarget().

◆ CanAutoCast()

bool Spell::CanAutoCast ( Unit target)
6994{
6995 ObjectGuid targetguid = target->GetGUID();
6996
6997 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
6998 {
7000 {
7001 if (m_spellInfo->StackAmount <= 1)
7002 {
7003 if (target->HasAuraEffect(m_spellInfo->Id, j))
7004 return false;
7005 }
7006 else
7007 {
7008 if (AuraEffect* aureff = target->GetAuraEffect(m_spellInfo->Id, j))
7009 if (aureff->GetBase()->GetStackAmount() >= m_spellInfo->StackAmount)
7010 return false;
7011 }
7012 }
7013 else if (m_spellInfo->Effects[j].IsAreaAuraEffect())
7014 {
7015 if (target->HasAuraEffect(m_spellInfo->Id, j))
7016 return false;
7017 }
7018 }
7019
7020 SpellCastResult result = CheckPetCast(target);
7021
7022 if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
7023 {
7025 //check if among target units, our WANTED target is as well (->only self cast spells return false)
7026 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7027 if (ihit->targetGUID == targetguid)
7028 return true;
7029 }
7030 return false; //target invalid
7031}
@ SPELL_EFFECT_APPLY_AURA
Definition: SharedDefines.h:784
@ SPELL_FAILED_UNIT_NOT_INFRONT
Definition: SharedDefines.h:1083
AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
Definition: Unit.cpp:5439
bool HasAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid caster=ObjectGuid::Empty) const
Definition: Unit.cpp:5613
Definition: SpellAuraEffects.h:39
SpellCastResult CheckPetCast(Unit *target)
Definition: Spell.cpp:6800
uint32 StackAmount
Definition: SpellInfo.h:371

References CheckPetCast(), SpellInfo::Effects, Unit::GetAuraEffect(), Object::GetGUID(), Unit::HasAuraEffect(), SpellInfo::Id, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, SelectSpellTargets(), SPELL_CAST_OK, SPELL_EFFECT_APPLY_AURA, SPELL_FAILED_UNIT_NOT_INFRONT, and SpellInfo::StackAmount.

Referenced by PetAI::UpdateAI().

◆ cancel()

void Spell::cancel ( bool  bySelf = false)
3711{
3713 return;
3714
3715 uint32 oldState = m_spellState;
3717
3718 m_autoRepeat = false;
3719 switch (oldState)
3720 {
3724
3726 {
3728 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3729 }
3730 [[fallthrough]];
3733 break;
3735 if (!bySelf)
3736 {
3737 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3738 if ((*ihit).missCondition == SPELL_MISS_NONE)
3739 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3740 unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
3741
3745
3748 }
3749
3751 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3752
3753 // spell is canceled-take mods and clear list
3754 if (Player* player = m_caster->GetSpellModOwner())
3755 player->RemoveSpellMods(this);
3756
3757 m_appliedMods.clear();
3758 break;
3759 default:
3760 break;
3761 }
3762
3764 if (m_selfContainer && *m_selfContainer == this)
3765 *m_selfContainer = nullptr;
3766
3767 // Do not remove current far sight object (already done in Spell::EffectAddFarsight) to prevent from reset viewpoint to player
3769 {
3771 }
3772
3773 if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
3775
3776 //set state back so finish will be processed
3777 m_spellState = oldState;
3778
3779 finish(false);
3780}
@ AURA_REMOVE_BY_CANCEL
Definition: SpellAuraDefines.h:393
@ SPELL_STATE_PREPARING
Definition: Spell.h:224
@ SPELL_STATE_CASTING
Definition: Spell.h:225
@ SPELL_EFFECT_ADD_FARSIGHT
Definition: SharedDefines.h:850
@ SPELL_ATTR0_COOLDOWN_ON_EVENT
Definition: SharedDefines.h:407
@ SPELL_FAILED_INTERRUPTED
Definition: SharedDefines.h:989
void SendCommand_Spell(T *o, ObjectGuid targetGUID, const char *prefix, uint32 id, int32 casttime)
Definition: ArenaSpectator.h:80
Map * FindMap() const
Definition: Object.h:523
bool NeedSendSpectatorData() const
Definition: Player.cpp:15349
void RemoveGameObject(GameObject *gameObj, bool del)
Definition: Unit.cpp:6142
bool RemoveDynObject(uint32 spellId)
Definition: Unit.cpp:6086
void SendChannelUpdate(uint32 time)
Definition: Spell.cpp:5177
void CancelGlobalCooldown()
Definition: Spell.cpp:8871
void SetReferencedFromCurrent(bool yes)
Definition: Spell.h:559
UsedSpellMods m_appliedMods
Definition: Spell.h:545

References AURA_REMOVE_BY_CANCEL, CancelGlobalCooldown(), WorldObject::FindMap(), finish(), Object::GetGUID(), Unit::GetSpellModOwner(), Object::GetTypeId(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellInfo::Id, SpellInfo::IsChanneled(), m_appliedMods, m_autoRepeat, m_caster, m_originalCasterGUID, m_selfContainer, m_spellInfo, m_spellState, m_UniqueTargetInfo, Player::NeedSendSpectatorData(), Unit::RemoveDynObject(), Unit::RemoveGameObject(), Player::RemoveSpellCooldown(), SendCastResult(), SendChannelUpdate(), ArenaSpectator::SendCommand_Spell(), SendInterrupted(), SetReferencedFromCurrent(), SPELL_ATTR0_COOLDOWN_ON_EVENT, SPELL_EFFECT_ADD_FARSIGHT, SPELL_FAILED_INTERRUPTED, SPELL_MISS_NONE, SPELL_STATE_CASTING, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, SPELL_STATE_PREPARING, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by _cast(), SpellEvent::Abort(), AddUnitTarget(), SpellScript::Cancel(), Unit::InterruptSpell(), update(), and SpellEvent::~SpellEvent().

◆ CancelGlobalCooldown()

void Spell::CancelGlobalCooldown ( )
protected
8872{
8874 return;
8875
8876 // Cancel global cooldown when interrupting current cast
8878 return;
8879
8880 // Only players or controlled units have global cooldown
8881 if (m_caster->GetCharmInfo())
8883 else if (m_caster->GetTypeId() == TYPEID_PLAYER)
8885}
@ CURRENT_GENERIC_SPELL
Definition: Unit.h:538
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition: Player.h:1781
void CancelGlobalCooldown(SpellInfo const *spellInfo)
Definition: CharmInfo.cpp:408
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition: CharmInfo.h:158
CharmInfo * GetCharmInfo()
Definition: Unit.h:1225
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition: Unit.h:1403
uint32 StartRecoveryTime
Definition: SpellInfo.h:351

References GlobalCooldownMgr::CancelGlobalCooldown(), CURRENT_GENERIC_SPELL, Unit::GetCharmInfo(), Unit::GetCurrentSpell(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), Object::GetTypeId(), m_caster, m_spellInfo, SpellInfo::StartRecoveryTime, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by cancel().

◆ CanExecuteTriggersOnHit()

bool Spell::CanExecuteTriggersOnHit ( uint8  effMask,
SpellInfo const *  triggeredByAura = nullptr 
) const
protected
8721{
8722 // Relentless strikes, proc only from first effect
8723 if (triggeredByAura && triggeredByAura->SpellIconID == 559)
8724 return effMask & (1 << EFFECT_0);
8725
8726 bool only_on_caster = (triggeredByAura && triggeredByAura->HasAttribute(SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET));
8727 // If triggeredByAura has SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET then it can only proc on a casted spell with TARGET_UNIT_CASTER
8728 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8729 {
8730 if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
8731 return true;
8732 }
8733 return effMask;
8734}
@ EFFECT_0
Definition: SharedDefines.h:31
@ TARGET_UNIT_CASTER
Definition: SharedDefines.h:1410
@ SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET
Definition: SharedDefines.h:531

References EFFECT_0, SpellInfo::Effects, SpellInfo::HasAttribute(), m_spellInfo, MAX_SPELL_EFFECTS, SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET, SpellInfo::SpellIconID, and TARGET_UNIT_CASTER.

Referenced by DoAllEffectOnTarget(), and DoTriggersOnSpellHit().

◆ CanOpenLock()

SpellCastResult Spell::CanOpenLock ( uint32  effIndex,
uint32  lockid,
SkillType skillid,
int32 reqSkillValue,
int32 skillValue 
)
protected
8345{
8346 if (!lockId) // possible case for GO and maybe for items.
8347 return SPELL_CAST_OK;
8348
8349 // Get LockInfo
8350 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
8351
8352 if (!lockInfo)
8354
8355 bool reqKey = false; // some locks not have reqs
8356
8357 for (int j = 0; j < MAX_LOCK_CASE; ++j)
8358 {
8359 switch (lockInfo->Type[j])
8360 {
8361 // check key item (many fit cases can be)
8362 case LOCK_KEY_ITEM:
8363 if (lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry() == lockInfo->Index[j])
8364 return SPELL_CAST_OK;
8365 reqKey = true;
8366 break;
8367 // check key skill (only single first fit case can be)
8368 case LOCK_KEY_SKILL:
8369 {
8370 reqKey = true;
8371
8372 // wrong locktype, skip
8373 if (uint32(m_spellInfo->Effects[effIndex].MiscValue) != lockInfo->Index[j])
8374 continue;
8375
8376 skillId = SkillByLockType(LockType(lockInfo->Index[j]));
8377
8378 if (skillId != SKILL_NONE)
8379 {
8380 reqSkillValue = lockInfo->Skill[j];
8381
8382 // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
8383 skillValue = m_CastItem || m_caster->GetTypeId() != TYPEID_PLAYER ?
8384 0 : m_caster->ToPlayer()->GetSkillValue(skillId);
8385
8386 // skill bonus provided by casting spell (mostly item spells)
8387 // add the effect base points modifier from the spell casted (cheat lock / skeleton key etc.)
8388 if ((m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
8390 {
8391 skillValue += m_spellInfo->Effects[effIndex].CalcValue();
8392 }
8393
8394 if (skillValue < reqSkillValue)
8396 }
8397
8398 return SPELL_CAST_OK;
8399 }
8400 case LOCK_KEY_SPELL:
8401 {
8402 if (m_spellInfo->Id == lockInfo->Index[j])
8403 {
8404 return SPELL_CAST_OK;
8405 }
8406 reqKey = true;
8407 break;
8408 }
8409 }
8410 }
8411
8412 if (reqKey)
8414
8415 return SPELL_CAST_OK;
8416}
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
#define MAX_LOCK_CASE
Definition: DBCStructure.h:1305
@ TARGET_GAMEOBJECT_ITEM_TARGET
Definition: SharedDefines.h:1430
LockType
Definition: SharedDefines.h:2591
@ LOCK_KEY_ITEM
Definition: SharedDefines.h:2585
@ LOCK_KEY_SKILL
Definition: SharedDefines.h:2586
@ LOCK_KEY_SPELL
Definition: SharedDefines.h:2587
@ SPELL_FAILED_BAD_TARGETS
Definition: SharedDefines.h:961
@ SPELL_FAILED_LOW_CASTLEVEL
Definition: SharedDefines.h:998
SkillType SkillByLockType(LockType locktype)
Definition: SharedDefines.h:3020
@ SKILL_NONE
Definition: SharedDefines.h:2864
@ SKILL_LOCKPICKING
Definition: SharedDefines.h:2975
uint16 GetSkillValue(uint32 skill) const
Definition: Player.cpp:5393
bool IsAbilityOfSkillType(uint32 skillType) const
Definition: SpellInfo.cpp:1004
Definition: DBCStructure.h:1308
uint32 Type[MAX_LOCK_CASE]
Definition: DBCStructure.h:1310
uint32 Index[MAX_LOCK_CASE]
Definition: DBCStructure.h:1311
uint32 Skill[MAX_LOCK_CASE]
Definition: DBCStructure.h:1312

References SpellInfo::Effects, Object::GetEntry(), Player::GetSkillValue(), Object::GetTypeId(), SpellInfo::Id, LockEntry::Index, SpellInfo::IsAbilityOfSkillType(), LOCK_KEY_ITEM, LOCK_KEY_SKILL, LOCK_KEY_SPELL, m_caster, m_CastItem, m_spellInfo, MAX_LOCK_CASE, LockEntry::Skill, SKILL_LOCKPICKING, SKILL_NONE, SkillByLockType(), sLockStore, SPELL_CAST_OK, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_LOW_CASTLEVEL, TARGET_GAMEOBJECT_ITEM_TARGET, Object::ToPlayer(), LockEntry::Type, and TYPEID_PLAYER.

Referenced by CheckCast(), and EffectOpenLock().

◆ cast()

void Spell::cast ( bool  skipCheck = false)
3783{
3784 Player* modOwner = m_caster->GetSpellModOwner();
3785 Spell* lastMod = nullptr;
3786 if (modOwner)
3787 {
3788 lastMod = modOwner->m_spellModTakingSpell;
3789 if (lastMod)
3790 modOwner->SetSpellModTakingSpell(lastMod, false);
3791 }
3792
3793 _cast(skipCheck);
3794
3795 if (lastMod)
3796 modOwner->SetSpellModTakingSpell(lastMod, true);
3797}
Spell * m_spellModTakingSpell
Definition: Player.h:2528
Definition: Spell.h:284
void _cast(bool skipCheck)
Definition: Spell.cpp:3799

References _cast(), Unit::GetSpellModOwner(), m_caster, Player::m_spellModTakingSpell, and Player::SetSpellModTakingSpell().

Referenced by Unit::AttackerStateUpdate(), prepare(), and update().

◆ CheckCast()

SpellCastResult Spell::CheckCast ( bool  strict)
Todo:
: determine if there is some flag to enable/disable the check
5640{
5641 // check death state
5644
5645 // Spectator check
5647 if (((Player const*)m_caster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT)
5648 return SPELL_FAILED_NOT_HERE;
5649
5651
5652 sScriptMgr->OnSpellCheckCast(this, strict, res);
5653
5654 if (res != SPELL_CAST_OK)
5655 return res;
5656
5657 // check cooldowns to prevent cheating
5659 {
5661 {
5662 //can cast triggered (by aura only?) spells while have this flag
5665
5667 {
5670 else
5672 }
5673
5674 // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
5677 }
5680 }
5681
5683 {
5686 }
5687
5688 // Check global cooldown
5691
5692 // only triggered spells can be processed an ended battleground
5695 if (bg->GetStatus() == STATUS_WAIT_LEAVE)
5697
5698 if (m_caster->GetTypeId() == TYPEID_PLAYER /*&& VMAP::VMapFactory::createOrGetVMapMgr()->isLineOfSightCalcEnabled()*/) // pussywizard: optimization (commented)
5699 {
5701 !m_caster->IsOutdoors())
5703
5707 }
5708
5709 // only check at first call, Stealth auras are already removed at second call
5710 // for now, ignore triggered spells
5712 {
5713 bool checkForm = true;
5714 // Ignore form req aura
5716 for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
5717 {
5718 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
5719 continue;
5720 checkForm = false;
5721 break;
5722 }
5723 if (checkForm)
5724 {
5725 // Cannot be used in this stance/form
5727 if (shapeError != SPELL_CAST_OK)
5728 return shapeError;
5729
5732 }
5733 }
5734
5736 for (Unit::AuraEffectList::const_iterator blockItr = blockSpells.begin(); blockItr != blockSpells.end(); ++blockItr)
5737 if (uint32((*blockItr)->GetMiscValue()) == m_spellInfo->SpellFamilyName)
5739
5740 bool reqCombat = true;
5742 for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
5743 {
5744 if ((*j)->IsAffectedOnSpell(m_spellInfo))
5745 {
5746 m_needComboPoints = false;
5747 if ((*j)->GetMiscValue() == 1)
5748 {
5749 reqCombat = false;
5750 break;
5751 }
5752 }
5753 }
5754
5755 // caster state requirements
5756 // not for triggered spells (needed by execute)
5758 {
5763
5764 // Note: spell 62473 requres CasterAuraSpell = triggering spell
5769
5770 if (reqCombat && m_caster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
5772 }
5773
5774 // Xinef: exploit protection
5776 {
5778 if (InstanceScript* instanceScript = m_caster->GetInstanceScript())
5779 if (instanceScript->IsEncounterInProgress())
5780 {
5781 if (Group* group = m_caster->ToPlayer()->GetGroup())
5782 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
5783 if (Player* member = itr->GetSource())
5784 if (member->IsInMap(m_caster))
5785 if (Unit* victim = member->GetVictim())
5786 if (victim->IsInCombat() && m_caster->GetDistance(victim) < m_caster->GetVisibilityRange())
5787 {
5788 m_caster->CombatStart(victim);
5789 victim->AddThreat(m_caster, 1.0f);
5790 break;
5791 }
5793 }
5794 }
5795
5796 // cancel autorepeat spells if cast start when moving
5797 // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
5799 {
5800 // skip stuck spell to allow use it in falling case and apply spell limitations at movement
5803 return SPELL_FAILED_MOVING;
5804 }
5805
5806 Vehicle* vehicle = m_caster->GetVehicle();
5808 {
5809 uint16 checkMask = 0;
5810 for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
5811 {
5812 SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex];
5814 {
5815 SpellShapeshiftFormEntry const* shapeShiftEntry = sSpellShapeshiftFormStore.LookupEntry(effInfo->MiscValue);
5816 if (shapeShiftEntry && (shapeShiftEntry->flags1 & 1) == 0) // unk flag
5817 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
5818 break;
5819 }
5820 }
5821
5824
5825 if (!checkMask)
5826 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
5827
5828 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
5829 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(m_caster);
5831 && (vehicleSeat->m_flags & checkMask) != checkMask && m_caster->GetTypeId() == TYPEID_PLAYER)
5833 }
5834
5835 // check spell cast conditions from database
5836 {
5839 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
5840 if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
5841 {
5842 // mLastFailedCondition can be nullptr if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
5843 if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
5844 {
5848 }
5849 if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
5852 }
5853 }
5854
5855 // Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
5856 // those spells may have incorrect target entries or not filled at all (for example 15332)
5857 // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead
5858 // also, such casts shouldn't be sent to client
5859 // Xinef: do not check explicit casts for self cast of triggered spells (eg. reflect case)
5861 {
5862 // Check explicit target for m_originalCaster - todo: get rid of such workarounds
5863 // Xinef: do not check explicit target for triggered spell casted on self with targetflag enemy
5865 {
5867 if (castResult != SPELL_CAST_OK)
5868 return castResult;
5869 }
5870 }
5871
5872 if (Unit* target = m_targets.GetUnitTarget())
5873 {
5874 SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false);
5875 if (castResult != SPELL_CAST_OK)
5876 return castResult;
5877
5878 if (target != m_caster)
5879 {
5880 // Must be behind the target
5881 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast<float>(M_PI), m_caster))
5883
5884 // Target must be facing you
5885 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
5887
5890 {
5891 bool castedByGameobject = false;
5892 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5894 {
5895 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5896 }
5897 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5898 {
5899 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5900 {
5901 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5902 }
5903 }
5904
5905 if (castedByGameobject)
5906 {
5907 // If spell casted by gameobject then ignore M2 models
5908 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5909 }
5910
5912 {
5914 }
5915 }
5916 }
5917 }
5918
5919 // Check for line of sight for spells with dest
5920 if (m_targets.HasDst())
5921 {
5922 float x, y, z;
5923 m_targets.GetDstPos()->GetPosition(x, y, z);
5924
5927 {
5928 bool castedByGameobject = false;
5929 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5931 {
5932 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5933 }
5934 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5935 {
5936 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5937 {
5938 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5939 }
5940 }
5941
5942 if (castedByGameobject)
5943 {
5944 // If spell casted by gameobject then ignore M2 models
5945 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5946 }
5947
5949 {
5951 }
5952 }
5953 }
5954
5955 // check pet presence
5956 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
5957 {
5958 if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET)
5959 {
5961 {
5962 if (m_triggeredByAuraSpell.spellInfo) // not report pet not existence for triggered spells
5964 else
5965 return SPELL_FAILED_NO_PET;
5966 }
5967 break;
5968 }
5969 }
5970 // Spell casted only on battleground
5972 if (!m_caster->ToPlayer()->InBattleground())
5974
5975 // do not allow spells to be cast in arenas
5976 // - with greater than 10 min CD without SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS flag
5977 // - with SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND flag
5980 if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
5981 if (mapEntry->IsBattleArena())
5983
5984 // zone check
5986 {
5987 uint32 zone, area;
5988 m_caster->GetZoneAndAreaId(zone, area);
5989
5991 m_caster->GetTypeId() == TYPEID_PLAYER ? m_caster->ToPlayer() : nullptr);
5992 if (locRes != SPELL_CAST_OK)
5993 return locRes;
5994 }
5995
5996 // not let players cast spells at mount (and let do it to creatures)
5999 {
6000 if (m_caster->IsInFlight())
6002 else
6004 }
6005
6006 SpellCastResult castResult = SPELL_CAST_OK;
6007
6008 // always (except passive spells) check items (focus object can be required for any type casts)
6009 if (!m_spellInfo->IsPassive())
6010 {
6011 // spell focus needs to be checked not only for players! there are vehicle spells that require spell focus
6012 castResult = CheckSpellFocus();
6013 if (castResult != SPELL_CAST_OK)
6014 return castResult;
6015
6016 castResult = CheckItems();
6017 if (castResult != SPELL_CAST_OK)
6018 return castResult;
6019 }
6020
6021 // Triggered spells also have range check
6023 castResult = CheckRange(strict);
6024 if (castResult != SPELL_CAST_OK)
6025 return castResult;
6026
6028 {
6029 castResult = CheckPower();
6030 if (castResult != SPELL_CAST_OK)
6031 return castResult;
6032 }
6033
6035 {
6036 return SPELL_CAST_OK;
6037 }
6038
6039 // xinef: do not skip triggered spells if they posses prevention type (eg. Bladestorm vs Hand of Protection)
6041 {
6043 if (castResult != SPELL_CAST_OK)
6044 return castResult;
6045
6046 // xinef: Enraged Regeneration: While this is active, the warrior is blocked from using abilities that trigger being enraged (which would do nothing and waste the cooldowns).
6048 {
6050 for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
6051 if (itr->type == m_spellInfo->Mechanic)
6053 }
6054 }
6055
6056 // script hook
6057 castResult = CallScriptCheckCastHandlers();
6058 if (castResult != SPELL_CAST_OK)
6059 return castResult;
6060
6061 bool hasDispellableAura = false;
6062 bool hasNonDispelEffect = false;
6063 uint32 dispelMask = 0;
6064 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6065 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
6066 {
6068 {
6069 hasDispellableAura = true;
6070 break;
6071 }
6072
6073 dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6074 }
6075 else if (m_spellInfo->Effects[i].IsEffect())
6076 {
6077 hasNonDispelEffect = true;
6078 break;
6079 }
6080
6081 if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered())
6082 {
6083 if (Unit* target = m_targets.GetUnitTarget())
6084 {
6085 // Xinef: do not allow to cast on hostile targets in sanctuary
6086 if (!m_caster->IsFriendlyTo(target))
6087 {
6088 if (m_caster->IsInSanctuary() || target->IsInSanctuary())
6089 {
6090 // Xinef: fix for duels
6091 Player* player = m_caster->ToPlayer();
6092 if (!player || !player->duel || target != player->duel->Opponent)
6094 }
6095 }
6096
6097 DispelChargesList dispelList;
6098 target->GetDispellableAuraList(m_caster, dispelMask, dispelList, m_spellInfo);
6099
6100 if (dispelList.empty())
6102 }
6103 }
6104
6105 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6106 {
6107 // for effects of spells that have only one target
6108 switch (m_spellInfo->Effects[i].Effect)
6109 {
6111 {
6114
6115 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET)
6116 break;
6117
6118 Pet* pet = m_caster->ToPlayer()->GetPet();
6119
6120 if (!pet)
6121 return SPELL_FAILED_NO_PET;
6122
6123 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6124
6125 if (!learn_spellproto)
6127
6128 if (m_spellInfo->SpellLevel > pet->GetLevel())
6129 return SPELL_FAILED_LOWLEVEL;
6130
6131 break;
6132 }
6134 {
6135 // check target only for unit target case
6137 {
6140
6141 Pet* pet = unitTarget->ToPet();
6142 if (!pet || pet->GetOwner() != m_caster)
6144
6145 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6146
6147 if (!learn_spellproto)
6149
6150 if (m_spellInfo->SpellLevel > pet->GetLevel())
6151 return SPELL_FAILED_LOWLEVEL;
6152 }
6153 break;
6154 }
6156 {
6157 uint32 glyphId = m_spellInfo->Effects[i].MiscValue;
6158 if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
6159 if (m_caster->HasAura(gp->SpellId))
6161 break;
6162 }
6164 {
6167
6168 Item* foodItem = m_targets.GetItemTarget();
6169 if (!foodItem)
6171
6172 Pet* pet = m_caster->ToPlayer()->GetPet();
6173
6174 if (!pet)
6175 return SPELL_FAILED_NO_PET;
6176
6177 if (!pet->HaveInDiet(foodItem->GetTemplate()))
6179
6180 if (!pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel))
6182
6183 if (m_caster->IsInCombat() || pet->IsInCombat())
6185
6186 break;
6187 }
6190 {
6191 // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
6193 if (Unit* target = m_targets.GetUnitTarget())
6194 if (target != m_caster && !target->HasActivePowerType(Powers(m_spellInfo->Effects[i].MiscValue)))
6196 break;
6197 }
6199 {
6201 {
6203 }
6204
6206 {
6207 // Warbringer - can't be handled in proc system - should be done before checkcast root check and charge effect process
6208 if (strict && m_caster->IsScriptOverriden(m_spellInfo, 6953))
6210 }
6212 {
6213 // Exception for Master's Call
6214 if (m_spellInfo->Id != 54216)
6215 {
6216 return SPELL_FAILED_ROOTED;
6217 }
6218 }
6220 if (Unit* target = m_targets.GetUnitTarget())
6221 if (!target->IsAlive())
6223 // Xinef: Pass only explicit unit target spells
6224 // pussywizard:
6226 {
6227 Unit* target = m_targets.GetUnitTarget();
6228 if (!target)
6230
6231 // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
6232 if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
6234
6235 float objSize = target->GetCombatReach();
6236 float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
6237
6238 m_preGeneratedPath = std::make_unique<PathGenerator>(m_caster);
6239 m_preGeneratedPath->SetPathLengthLimit(range);
6240
6241 // first try with raycast, if it fails fall back to normal path
6242 bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
6243 if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
6244 return SPELL_FAILED_NOPATH;
6245 else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
6246 return SPELL_FAILED_NOPATH;
6247 else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line
6248 return SPELL_FAILED_NOPATH;
6249
6250 m_preGeneratedPath->ShortenPathUntilDist(G3D::Vector3(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()), objSize); // move back
6251 }
6252 if (Player* player = m_caster->ToPlayer())
6253 player->SetCanTeleport(true);
6254 break;
6255 }
6257 {
6260
6263
6264 Creature* creature = m_targets.GetUnitTarget()->ToCreature();
6265 if (!creature->IsCritter() && !creature->loot.isLooted())
6267
6268 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
6269
6270 int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
6271 int32 TargetLevel = m_targets.GetUnitTarget()->GetLevel();
6272 int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
6273 if (ReqValue > skillValue)
6275
6276 break;
6277 }
6279 {
6280 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
6281 m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
6282 break;
6283
6284 if (m_caster->GetTypeId() != TYPEID_PLAYER // only players can open locks, gather etc.
6285 // we need a go target in case of TARGET_GAMEOBJECT_TARGET
6286 || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
6288
6289 Item* pTempItem = nullptr;
6291 {
6292 if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData())
6293 pTempItem = pTrade->GetTraderData()->GetItem(TradeSlots(m_targets.GetItemTargetGUID().GetRawValue()));
6294 }
6297
6298 // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
6299 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
6301 (!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked()))
6303
6304 // We must also ensure the gameobject we are opening is still closed by the time the spell finishes.
6305 if (GameObject* go = m_targets.GetGOTarget())
6306 {
6307 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR && go->GetGoState() != GO_STATE_READY)
6308 {
6310 }
6311 }
6312 if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
6314 {
6315 if (m_targets.GetGOTarget() && m_targets.GetGOTarget()->GetEntry() == 179697)
6316 {
6317 if (!m_caster->ToPlayer()->CanUseBattlegroundObject(nullptr))
6319 }
6320 else if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners, or Gurubashi chest
6323 }
6324
6325 // get the lock entry
6326 uint32 lockId = 0;
6327 if (GameObject* go = m_targets.GetGOTarget())
6328 {
6329 lockId = go->GetGOInfo()->GetLockId();
6330 if (!lockId)
6332 }
6333 else if (Item* itm = m_targets.GetItemTarget())
6334 lockId = itm->GetTemplate()->LockID;
6335
6336 SkillType skillId = SKILL_NONE;
6337 int32 reqSkillValue = 0;
6338 int32 skillValue = 0;
6339
6340 // check lock compatibility
6341 SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
6342 if (res != SPELL_CAST_OK)
6343 return res;
6344
6345 // chance for fail at lockpicking attempt
6346 // second check prevent fail at rechecks
6347 // herbalism and mining cannot fail as of patch 3.1.0
6348 if (skillId != SKILL_NONE && skillId != SKILL_HERBALISM && skillId != SKILL_MINING && (!m_selfContainer || ((*m_selfContainer) != this)))
6349 {
6350 // chance for failure in orange lockpick
6351 if (skillId == SKILL_LOCKPICKING && reqSkillValue > irand(skillValue - 25, skillValue + 37))
6352 {
6354 }
6355 }
6356 break;
6357 }
6359 {
6360 Unit* unitCaster = m_caster->ToUnit();
6361 if (!unitCaster)
6362 {
6364 }
6365
6366 Creature* pet = unitCaster->GetGuardianPet();
6367 if (pet)
6368 {
6369 if (pet->IsAlive())
6370 {
6372 }
6373 }
6374 else if (Player* playerCaster = m_caster->ToPlayer())
6375 {
6376 PetStable& petStable = playerCaster->GetOrInitPetStable();
6377 if (!petStable.CurrentPet && petStable.UnslottedPets.empty())
6378 {
6379 return SPELL_FAILED_NO_PET;
6380 }
6381 }
6382
6383 break;
6384 }
6385 // This is generic summon effect
6387 {
6388 SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB);
6389 if (!SummonProperties || m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST))
6390 break;
6391 switch (SummonProperties->Category)
6392 {
6394 if (m_caster->GetPetGUID())
6396 [[fallthrough]];
6398 if (m_caster->GetCharmGUID())
6400 break;
6401 }
6402 break;
6403 }
6405 {
6407 {
6412 }
6413 break;
6414 }
6416 {
6417 Unit* unitCaster = m_caster->ToUnit();
6418 if (!unitCaster)
6420
6422 {
6423 if (m_caster->GetPetGUID())
6425 if (m_caster->GetCharmGUID())
6427 }
6428
6430 if (Pet* pet = m_caster->ToPlayer()->GetPet())
6431 pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID()); //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
6432
6433 Player* playerCaster = unitCaster->ToPlayer();
6434 if (playerCaster && playerCaster->GetPetStable())
6435 {
6436 std::pair<PetStable::PetInfo const*, PetSaveMode> info = Pet::GetLoadPetInfo(*playerCaster->GetPetStable(), m_spellInfo->Effects[i].MiscValue, 0, false);
6437 if (info.first)
6438 {
6439 if (info.first->Type == HUNTER_PET)
6440 {
6441 if (!info.first->Health)
6442 {
6443 playerCaster->SendTameFailure(PET_TAME_DEAD);
6445 }
6446
6447 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(info.first->CreatureId);
6448 if (!creatureInfo || !creatureInfo->IsTameable(playerCaster->CanTameExoticPets()))
6449 {
6450 // if problem in exotic pet
6451 if (creatureInfo && creatureInfo->IsTameable(true))
6453 else
6455
6457 }
6458 }
6459 }
6460 else if (!m_spellInfo->Effects[i].MiscValue) // when miscvalue is present it is allowed to create new pets
6461 {
6464 }
6465 }
6466 break;
6467 }
6469 {
6472 if (!m_caster->GetTarget())
6474
6476 if (!target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
6478
6479 // Xinef: Implement summon pending error
6480 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6482
6483 // check if our map is dungeon
6484 MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
6485 if (map->IsDungeon())
6486 {
6487 uint32 mapId = m_caster->GetMap()->GetId();
6488 Difficulty difficulty = m_caster->GetMap()->GetDifficulty();
6489 /*if (map->IsRaid())
6490 if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
6491 if (targetBind->perm && targetBind != m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
6492 return SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE;*/
6493
6494 InstanceTemplate const* instance = sObjectMgr->GetInstanceTemplate(mapId);
6495 if (!instance)
6497 if (!target->Satisfy(sObjectMgr->GetAccessRequirement(mapId, difficulty), mapId))
6499 }
6500 break;
6501 }
6502 // RETURN HERE
6504 {
6507
6508 Player* playerCaster = m_caster->ToPlayer();
6509 //
6510 if (!(playerCaster->GetTarget()))
6512
6514
6515 if (!target ||
6516 !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
6518
6519 // Xinef: Implement summon pending error
6520 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6522
6523 break;
6524 }
6525 case SPELL_EFFECT_LEAP:
6527 {
6528 //Do not allow to cast it before BG starts.
6530 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6531 if (bg->GetStatus() != STATUS_IN_PROGRESS)
6533 break;
6534 }
6536 {
6539
6540 bool found = false;
6542 for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
6543 {
6544 if( itr->second->GetBase()->IsPassive() )
6545 continue;
6546
6547 if( !itr->second->IsPositive() )
6548 continue;
6549
6550 found = true;
6551 break;
6552 }
6553
6554 if( !found )
6556
6557 break;
6558 }
6560 {
6562 {
6564 return SPELL_FAILED_ROOTED;
6565 else
6567 }
6568 break;
6569 }
6570 // xinef: do not allow to use leaps while rooted
6571 case SPELL_EFFECT_JUMP:
6573 {
6575 return SPELL_FAILED_ROOTED;
6576 break;
6577 }
6579 if (!sScriptMgr->CanSelectSpecTalent(this))
6581 // can't change during already started arena/battleground
6583 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6584 if (bg->GetStatus() == STATUS_IN_PROGRESS)
6586 break;
6587 default:
6588 break;
6589 }
6590 }
6591
6592 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6593 {
6594 switch (m_spellInfo->Effects[i].ApplyAuraName)
6595 {
6596 case SPELL_AURA_DUMMY:
6597 break;
6599 {
6601 return SPELL_FAILED_NO_PET;
6602
6603 Pet* pet = m_caster->ToPlayer()->GetPet();
6604 if (!pet)
6605 return SPELL_FAILED_NO_PET;
6606
6607 if (pet->GetCharmerGUID())
6608 return SPELL_FAILED_CHARMED;
6609 break;
6610 }
6614 {
6615 if (m_caster->GetCharmerGUID())
6616 return SPELL_FAILED_CHARMED;
6617
6618 // Xinef: allow SPELL_AURA_MOD_POSSESS to posses target if caster has some pet
6620 {
6621 if (m_caster->GetPetGUID())
6623
6624 if (m_caster->GetCharmGUID())
6626 }
6627 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
6628 {
6629 if (m_caster->GetCharmGUID())
6631 }
6632
6633 if (Unit* target = m_targets.GetUnitTarget())
6634 {
6635 if (target->GetTypeId() == TYPEID_UNIT && target->ToCreature()->IsVehicle())
6637
6638 if (target->IsMounted())
6640
6641 if (target->GetCharmerGUID())
6642 return SPELL_FAILED_CHARMED;
6643
6644 if (target->GetOwnerGUID() && target->GetOwnerGUID().IsPlayer())
6646
6647 if (target->IsPet() && (!target->GetOwner() || target->GetOwner()->ToPlayer()))
6649
6650 int32 damage = CalculateSpellDamage(i, target);
6651 if (damage && int32(target->GetLevel()) > damage)
6653 }
6654
6655 break;
6656 }
6657 case SPELL_AURA_MOUNTED:
6658 {
6659 // Disallow casting flying mounts in water
6662
6663 // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
6664 bool allowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
6665 InstanceTemplate const* it = sObjectMgr->GetInstanceTemplate(m_caster->GetMapId());
6666 if (it)
6667 allowMount = it->AllowMount;
6668 if (m_caster->GetTypeId() == TYPEID_PLAYER && !allowMount && !m_spellInfo->AreaGroupId)
6670
6673
6674 // xinef: dont allow to cast mounts in specific transforms
6675 if (m_caster->getTransForm())
6676 if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(m_caster->getTransForm()))
6677 if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) &&
6678 !transformSpellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_ALLOW_WHILE_MOUNTED | SPELL_ATTR0_AURA_IS_DEBUFF)))
6680
6681 break;
6682 }
6684 {
6685 if (!m_targets.GetUnitTarget())
6687
6688 // can be casted at non-friendly unit or own pet/charm
6691
6692 break;
6693 }
6694 case SPELL_AURA_FLY:
6696 {
6697 // Xinef: added water check
6698 if (m_caster->IsInWater())
6700
6701 // not allow cast fly spells if not have req. skills (all spells is self target)
6702 // allow always ghost flight spells
6704 {
6705 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
6706 if (AreaTableEntry const* pArea = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId()))
6707 if ((pArea->flags & AREA_FLAG_NO_FLY_ZONE) || (Bf && !Bf->CanFlyIn()))
6708 return SPELL_FAILED_NOT_HERE;
6709 }
6710 break;
6711 }
6713 {
6714 if (m_spellInfo->Effects[i].IsTargetingArea())
6715 break;
6716
6718 break;
6719
6720 if (!m_targets.GetUnitTarget())
6722
6725
6726 break;
6727 }
6728 case SPELL_AURA_HOVER:
6729 {
6731 {
6733 }
6734 break;
6735 }
6737 {
6738 if (m_caster && m_caster->HasAura(23397)) // Nefarian Class Call (Warrior): Berserk -- Nefertum: I don't really like this but I didn't find another way.
6739 {
6741 }
6742 break;
6743 }
6744 default:
6745 break;
6746 }
6747 }
6748
6749 // check trade slot case (last, for allow catch any another cast problems)
6751 {
6752 if (m_CastItem)
6754
6757
6758 TradeData* my_trade = m_caster->ToPlayer()->GetTradeData();
6759
6760 if (!my_trade)
6762
6764 if (slot != TRADE_SLOT_NONTRADED)
6766
6767 if (!IsTriggered())
6768 if (my_trade->GetSpell())
6770 }
6771
6772 // check if caster has at least 1 combo point on target for spells that require combo points
6774 {
6776 {
6778 {
6780 }
6781 }
6782 else
6783 {
6784 if (!m_caster->GetComboPoints())
6785 {
6787 }
6788 }
6789 }
6790
6791 // xinef: check relic cooldown
6795
6796 // all ok
6797 return SPELL_CAST_OK;
6798}
constexpr auto IN_MILLISECONDS
Definition: Common.h:52
constexpr auto MINUTE
Definition: Common.h:46
std::int32_t int32
Definition: Define.h:103
std::uint16_t uint16
Definition: Define.h:108
int32 irand(int32 min, int32 max)
Definition: Random.cpp:37
#define SPECTATOR_SPELL_BINDSIGHT
Definition: ArenaSpectator.h:38
#define sBattlefieldMgr
Definition: BattlefieldMgr.h:77
@ STATUS_WAIT_LEAVE
Definition: Battleground.h:198
@ STATUS_IN_PROGRESS
Definition: Battleground.h:197
#define sConditionMgr
Definition: ConditionMgr.h:289
@ CONDITION_SOURCE_TYPE_SPELL
Definition: ConditionMgr.h:139
std::list< Condition * > ConditionList
Definition: ConditionMgr.h:236
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
DBCStorage< SpellShapeshiftFormEntry > sSpellShapeshiftFormStore(SpellShapeshiftFormEntryfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
DBCStorage< GlyphPropertiesEntry > sGlyphPropertiesStore(GlyphPropertiesfmt)
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
@ GO_STATE_READY
Definition: GameObjectData.h:691
@ INVTYPE_RELIC
Definition: ItemTemplate.h:292
@ HUNTER_PET
Definition: PetDefines.h:32
@ PLAYER_ALLOW_ONLY_ABILITY
Definition: Player.h:497
TradeSlots
Definition: TradeData.h:28
@ TRADE_SLOT_NONTRADED
Definition: TradeData.h:31
#define WORLD_TRIGGER
Definition: Unit.h:37
std::list< std::pair< Aura *, uint8 > > DispelChargesList
Definition: Unit.h:77
@ MOVEMENTFLAG_FALLING_FAR
Definition: UnitDefines.h:357
@ CLASS_CONTEXT_PET
Definition: UnitDefines.h:215
@ UNIT_FLAG2_ALLOW_CHEAT_SPELLS
Definition: UnitDefines.h:285
@ UNIT_STATE_ROOT
Definition: UnitDefines.h:159
@ UNIT_STATE_CHARGING
Definition: UnitDefines.h:166
@ UNIT_FLAG_SKINNABLE
Definition: UnitDefines.h:255
LineOfSightChecks
Definition: Map.h:191
@ LINEOFSIGHT_ALL_CHECKS
Definition: Map.h:198
@ PATHFIND_NOPATH
Definition: PathGenerator.h:51
@ PATHFIND_SHORT
Definition: PathGenerator.h:53
@ PATHFIND_INCOMPLETE
Definition: PathGenerator.h:50
@ SPELL_AURA_ABILITY_IGNORE_AURASTATE
Definition: SpellAuraDefines.h:325
@ SPELL_AURA_MOD_SHAPESHIFT
Definition: SpellAuraDefines.h:99
@ SPELL_AURA_MOD_IGNORE_SHAPESHIFT
Definition: SpellAuraDefines.h:338
@ SPELL_AURA_PERIODIC_MANA_LEECH
Definition: SpellAuraDefines.h:127
@ SPELL_AURA_MOD_POSSESS_PET
Definition: SpellAuraDefines.h:191
@ SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS
Definition: SpellAuraDefines.h:190
@ SPELL_AURA_DUMMY
Definition: SpellAuraDefines.h:67
@ SPELL_AURA_FLY
Definition: SpellAuraDefines.h:264
@ SPELL_AURA_HOVER
Definition: SpellAuraDefines.h:169
@ SPELL_AURA_MOUNTED
Definition: SpellAuraDefines.h:141
@ SPELL_AURA_AOE_CHARM
Definition: SpellAuraDefines.h:240
@ SPELL_AURA_MOD_POSSESS
Definition: SpellAuraDefines.h:65
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
Definition: SpellAuraDefines.h:270
@ SPELL_AURA_BLOCK_SPELL_FAMILY
Definition: SpellAuraDefines.h:360
@ SPELL_FLAG_REDIRECTED
Definition: Spell.h:83
@ AURA_INTERRUPT_FLAG_NOT_SEATED
Definition: SpellDefines.h:62
@ AURA_INTERRUPT_FLAG_MOUNT
Definition: SpellDefines.h:61
@ TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
Will ignore GCD.
Definition: SpellDefines.h:133
@ TRIGGERED_IGNORE_CASTER_AURASTATE
Will ignore shapeshift checks.
Definition: SpellDefines.h:143
@ TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE
Will ignore caster aura states including combat requirements and death state.
Definition: SpellDefines.h:144
@ TRIGGERED_IGNORE_SHAPESHIFT
Will not adjust facing to target (if any)
Definition: SpellDefines.h:142
@ TRIGGERED_IGNORE_GCD
Not triggered.
Definition: SpellDefines.h:132
@ TRIGGERED_IGNORE_EFFECTS
Periodic aura tick wont be reset on override.
Definition: SpellDefines.h:151
@ TRIGGERED_IGNORE_CASTER_AURAS
Will ignore mounted/on vehicle restrictions.
Definition: SpellDefines.h:145
std::vector< SpellImmune > SpellImmuneList
Definition: SpellDefines.h:180
@ TARGET_FLAG_UNIT_ENEMY
Definition: SpellInfo.h:53
@ TARGET_FLAG_ITEM
Definition: SpellInfo.h:50
@ SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER
Definition: SpellInfo.h:192
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition: SpellInfo.h:193
#define SPELL_RELIC_COOLDOWN
Definition: SpellMgr.h:34
@ VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL
Definition: DBCEnums.h:456
@ VEHICLE_SEAT_FLAG_UNCONTROLLED
Definition: DBCEnums.h:457
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition: DBCEnums.h:458
Difficulty
Definition: DBCEnums.h:266
@ AREA_FLAG_NO_FLY_ZONE
Definition: DBCEnums.h:262
@ GAMEOBJECT_TYPE_TRAP
Definition: SharedDefines.h:1566
@ GAMEOBJECT_TYPE_DOOR
Definition: SharedDefines.h:1560
Powers
Definition: SharedDefines.h:268
@ POWER_MANA
Definition: SharedDefines.h:269
@ SPELL_ATTR7_DEBUG_SPELL
Definition: SharedDefines.h:644
@ SPELL_EFFECT_LEAP
Definition: SharedDefines.h:807
@ SPELL_EFFECT_POWER_BURN
Definition: SharedDefines.h:840
@ SPELL_EFFECT_STUCK
Definition: SharedDefines.h:862
@ SPELL_EFFECT_SUMMON_RAF_FRIEND
Definition: SharedDefines.h:930
@ SPELL_EFFECT_APPLY_GLYPH
Definition: SharedDefines.h:852
@ SPELL_EFFECT_FEED_PET
Definition: SharedDefines.h:879
@ SPELL_EFFECT_SUMMON_PLAYER
Definition: SharedDefines.h:863
@ SPELL_EFFECT_JUMP_DEST
Definition: SharedDefines.h:820
@ SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
Definition: SharedDefines.h:821
@ SPELL_EFFECT_RESURRECT_PET
Definition: SharedDefines.h:887
@ SPELL_EFFECT_LEAP_BACK
Definition: SharedDefines.h:916
@ SPELL_EFFECT_SUMMON
Definition: SharedDefines.h:806
@ SPELL_EFFECT_POWER_DRAIN
Definition: SharedDefines.h:786
@ SPELL_EFFECT_RESURRECT
Definition: SharedDefines.h:796
@ SPELL_EFFECT_CHARGE
Definition: SharedDefines.h:874
@ SPELL_EFFECT_RESURRECT_NEW
Definition: SharedDefines.h:891
@ SPELL_EFFECT_TALENT_SPEC_SELECT
Definition: SharedDefines.h:940
@ SPELL_EFFECT_LEARN_SPELL
Definition: SharedDefines.h:814
@ SPELL_EFFECT_JUMP
Definition: SharedDefines.h:819
@ SPELL_EFFECT_SKINNING
Definition: SharedDefines.h:873
@ SPELL_EFFECT_CREATE_TAMED_PET
Definition: SharedDefines.h:931
@ SPELL_EFFECT_OPEN_LOCK
Definition: SharedDefines.h:811
@ SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
Definition: SharedDefines.h:904
@ SPELL_EFFECT_LEARN_PET_SPELL
Definition: SharedDefines.h:835
@ SPELL_PREVENTION_TYPE_NONE
Definition: SharedDefines.h:1553
@ SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT
Definition: SharedDefines.h:593
@ TARGET_UNIT_PET
Definition: SharedDefines.h:1414
@ TARGET_GAMEOBJECT_TARGET
Definition: SharedDefines.h:1427
@ SPELL_ATTR2_IGNORE_LINE_OF_SIGHT
Definition: SharedDefines.h:458
@ SPELL_ATTR1_INITIATE_COMBAT
Definition: SharedDefines.h:428
@ SPELL_ATTR3_ONLY_BATTLEGROUNDS
Definition: SharedDefines.h:504
@ PET_TAME_NOPET_AVAILABLE
Definition: SharedDefines.h:3683
@ PET_TAME_DEAD
Definition: SharedDefines.h:3686
@ PET_TAME_CANT_CONTROL_EXOTIC
Definition: SharedDefines.h:3688
@ CLASS_WARLOCK
Definition: SharedDefines.h:149
@ IMMUNITY_MECHANIC
Definition: SharedDefines.h:1399
@ SPELLFAMILY_WARRIOR
Definition: SharedDefines.h:3532
SpellCustomErrors
Definition: SharedDefines.h:1142
@ SPELL_CUSTOM_ERROR_GM_ONLY
Definition: SharedDefines.h:1208
SpellAttr0
Definition: SharedDefines.h:381
@ SPELL_ATTR0_ONLY_INDOORS
Definition: SharedDefines.h:396
@ SPELL_ATTR0_AURA_IS_DEBUFF
Definition: SharedDefines.h:408
@ SPELL_ATTR0_ONLY_OUTDOORS
Definition: SharedDefines.h:397
@ SPELL_ATTR0_ALLOW_WHILE_MOUNTED
Definition: SharedDefines.h:406
@ SPELL_ATTR0_PASSIVE
Definition: SharedDefines.h:388
@ SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD
Definition: SharedDefines.h:405
@ SPELL_ATTR0_ONLY_STEALTHED
Definition: SharedDefines.h:399
AuraStateType
Definition: SharedDefines.h:1288
DispelType
Definition: SharedDefines.h:1371
@ SPELL_FAILED_TARGET_NOT_LOOTED
Definition: SharedDefines.h:1070
@ SPELL_FAILED_NOT_INFRONT
Definition: SharedDefines.h:1010
@ SPELL_FAILED_MOVING
Definition: SharedDefines.h:1000
@ SPELL_FAILED_NOT_MOUNTED
Definition: SharedDefines.h:1013
@ SPELL_FAILED_AFFECTING_COMBAT
Definition: SharedDefines.h:950
@ SPELL_FAILED_CASTER_AURASTATE
Definition: SharedDefines.h:971
@ SPELL_FAILED_NOTHING_TO_DISPEL
Definition: SharedDefines.h:1035
@ SPELL_FAILED_NOT_KNOWN
Definition: SharedDefines.h:1012
@ SPELL_FAILED_FOOD_LOWLEVEL
Definition: SharedDefines.h:984
@ SPELL_FAILED_NOT_HERE
Definition: SharedDefines.h:1009
@ SPELL_FAILED_ROOTED
Definition: SharedDefines.h:1052
@ SPELL_FAILED_WRONG_PET_FOOD
Definition: SharedDefines.h:1084
@ SPELL_FAILED_CUSTOM_ERROR
Definition: SharedDefines.h:1121
@ SPELL_FAILED_SUMMON_PENDING
Definition: SharedDefines.h:1132
@ SPELL_FAILED_DAMAGE_IMMUNE
Definition: SharedDefines.h:1095
@ SPELL_FAILED_BAD_IMPLICIT_TARGETS
Definition: SharedDefines.h:960
@ SPELL_FAILED_TRY_AGAIN
Definition: SharedDefines.h:1081
@ SPELL_FAILED_NO_COMBO_POINTS
Definition: SharedDefines.h:1027
@ SPELL_FAILED_ALREADY_HAVE_SUMMON
Definition: SharedDefines.h:956
@ SPELL_FAILED_ALREADY_OPEN
Definition: SharedDefines.h:957
@ SPELL_FAILED_NOT_TRADING
Definition: SharedDefines.h:1020
@ SPELL_FAILED_NOTHING_TO_STEAL
Definition: SharedDefines.h:1036
@ SPELL_FAILED_NO_MOUNTS_ALLOWED
Definition: SharedDefines.h:1032
@ SPELL_FAILED_NOT_IN_BATTLEGROUND
Definition: SharedDefines.h:1115
@ SPELL_FAILED_NOT_BEHIND
Definition: SharedDefines.h:1006
@ SPELL_FAILED_ALREADY_HAVE_CHARM
Definition: SharedDefines.h:955
@ SPELL_FAILED_TARGET_NOT_IN_INSTANCE
Definition: SharedDefines.h:1086
@ SPELL_FAILED_HIGHLEVEL
Definition: SharedDefines.h:985
@ SPELL_FAILED_LOWLEVEL
Definition: SharedDefines.h:997
@ SPELL_FAILED_NOT_READY
Definition: SharedDefines.h:1016
@ SPELL_FAILED_ONLY_BATTLEGROUNDS
Definition: SharedDefines.h:1091
@ SPELL_FAILED_NOT_IN_ARENA
Definition: SharedDefines.h:1100
@ SPELL_FAILED_ITEM_ALREADY_ENCHANTED
Definition: SharedDefines.h:991
@ SPELL_FAILED_ONLY_STEALTHED
Definition: SharedDefines.h:1044
@ SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED
Definition: SharedDefines.h:1067
@ SPELL_FAILED_ONLY_ABOVEWATER
Definition: SharedDefines.h:1037
@ SPELL_FAILED_CANT_BE_CHARMED
Definition: SharedDefines.h:962
@ SPELL_FAILED_CASTER_DEAD
Definition: SharedDefines.h:972
@ SPELL_FAILED_NOT_ON_MOUNTED
Definition: SharedDefines.h:1104
@ SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW
Definition: SharedDefines.h:1131
@ SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED
Definition: SharedDefines.h:1135
@ SPELL_FAILED_TARGET_UNSKINNABLE
Definition: SharedDefines.h:1075
@ SPELL_FAILED_NOT_SHAPESHIFT
Definition: SharedDefines.h:1017
@ SPELL_FAILED_UNIQUE_GLYPH
Definition: SharedDefines.h:1125
@ SPELL_FAILED_ONLY_OUTDOORS
Definition: SharedDefines.h:1042
@ SPELL_FAILED_CHARMED
Definition: SharedDefines.h:973
@ SPELL_FAILED_LINE_OF_SIGHT
Definition: SharedDefines.h:996
@ SPELL_FAILED_SPELL_IN_PROGRESS
Definition: SharedDefines.h:1054
@ SPELL_FAILED_NO_PET
Definition: SharedDefines.h:1033
@ SPELL_FAILED_NOPATH
Definition: SharedDefines.h:1005
@ SPELL_FAILED_SPELL_UNAVAILABLE
Definition: SharedDefines.h:1056
@ SPELL_FAILED_ONLY_INDOORS
Definition: SharedDefines.h:1039
@ SPELL_FAILED_NOT_ON_TAXI
Definition: SharedDefines.h:1014
@ SPELL_FAILED_TARGET_FRIENDLY
Definition: SharedDefines.h:1064
@ SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS
Definition: SharedDefines.h:547
@ SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND
Definition: SharedDefines.h:546
@ SUMMON_CATEGORY_PET
Definition: SharedDefines.h:3285
@ SUMMON_CATEGORY_PUPPET
Definition: SharedDefines.h:3286
SkillType
Definition: SharedDefines.h:2863
@ SKILL_MINING
Definition: SharedDefines.h:2919
@ SKILL_HERBALISM
Definition: SharedDefines.h:2915
@ SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE
Definition: SharedDefines.h:616
bool IsPathfindingEnabled(const Map *map)
Definition: DisableMgr.cpp:411
Player * FindPlayer(ObjectGuid const guid)
Definition: ObjectAccessor.cpp:248
Seconds GetGameTime()
Definition: GameTime.cpp:38
Definition: Battlefield.h:206
bool CanFlyIn()
Return if we can use mount in battlefield.
Definition: Battlefield.h:342
Definition: Battleground.h:298
Definition: ConditionMgr.h:181
Condition * mLastFailedCondition
Definition: ConditionMgr.h:183
WorldObject * mConditionTargets[MAX_CONDITION_TARGETS]
Definition: ConditionMgr.h:182
uint32 ErrorType
Definition: ConditionMgr.h:204
uint8 ConditionTarget
Definition: ConditionMgr.h:208
uint32 ErrorTextId
Definition: ConditionMgr.h:205
Loot loot
Definition: Creature.h:221
CreatureTemplate const * GetCreatureTemplate() const
Definition: Creature.h:200
bool IsSpellProhibited(SpellSchoolMask idSchoolMask) const
Definition: Creature.cpp:2800
SkillType GetRequiredLootSkill() const
Definition: CreatureData.h:260
bool IsTameable(bool exotic) const
Definition: CreatureData.h:277
Definition: TemporarySummon.h:40
Definition: GameObject.h:121
GameObjectTemplate const * GetGOInfo() const
Definition: GameObject.h:137
uint32 type
Definition: GameObjectData.h:34
bool IsLocked() const
Definition: Item.h:253
ItemTemplate const * GetTemplate() const
Definition: Item.cpp:545
bool IsPotion() const
Definition: Item.h:334
uint32 ItemLevel
Definition: ItemTemplate.h:643
uint32 LockID
Definition: ItemTemplate.h:677
uint32 InventoryType
Definition: ItemTemplate.h:640
Unit * ToUnit()
Definition: Object.h:203
Map * GetMap() const
Definition: Object.h:522
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1192
bool IsWithinLOSInMap(WorldObject const *obj, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, Optional< float > collisionHeight={ }, Optional< float > combatReach={ }) const
Definition: Object.cpp:1347
bool IsOutdoors() const
Definition: Object.cpp:3166
bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS) const
Definition: Object.cpp:1326
float GetVisibilityRange() const
Definition: Object.cpp:1645
uint32 GetAreaId() const
Definition: Object.cpp:3149
uint32 GetZoneId() const
Definition: Object.cpp:3141
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition: Object.cpp:3157
uint64 GetRawValue() const
Definition: ObjectGuid.h:142
bool IsPlayer() const
Definition: ObjectGuid.h:168
bool IsGameObject() const
Definition: ObjectGuid.h:171
void GetPosition(float &x, float &y) const
Definition: Position.h:122
uint32 GetMapId() const
Definition: Position.h:276
Player * GetOwner() const
Definition: Pet.cpp:2493
bool HaveInDiet(ItemTemplate const *item) const
Definition: Pet.cpp:1439
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel) const
Definition: Pet.cpp:1457
static std::pair< PetStable::PetInfo const *, PetSaveMode > GetLoadPetInfo(PetStable const &stable, uint32 petEntry, uint32 petnumber, bool current)
Definition: Pet.cpp:170
Definition: PetDefines.h:202
Optional< PetInfo > CurrentPet
Definition: PetDefines.h:225
std::vector< PetInfo > UnslottedPets
Definition: PetDefines.h:228
void SetCanTeleport(bool value)
Definition: Player.h:2474
bool IsInSameRaidWith(Player const *p) const
Definition: Player.h:1862
bool CanTameExoticPets() const
Definition: Player.h:2165
bool CanUseBattlegroundObject(GameObject *gameobject) const
Definition: Player.cpp:13166
bool InBattleground() const
Definition: Player.h:2228
PetStable * GetPetStable()
Definition: Player.h:1201
Battleground * GetBattleground(bool create=false) const
Definition: Player.cpp:12148
WorldSession * GetSession() const
Definition: Player.h:1974
bool HasSpellCooldown(uint32 spell_id) const override
Definition: Player.cpp:16281
uint32 GetLastPotionId()
Definition: Player.h:1788
Group * GetGroup()
Definition: Player.h:2444
bool IsGameMaster() const
Definition: Player.h:1157
time_t GetSummonExpireTimer() const
Definition: Player.h:1100
bool Satisfy(DungeonProgressionRequirements const *ar, uint32 target_map, bool report=false)
Definition: PlayerStorage.cpp:6720
bool HasPlayerFlag(PlayerFlags flags) const
Definition: Player.h:1107
std::unique_ptr< DuelInfo > duel
Definition: Player.h:1854
Item * GetItemByGuid(ObjectGuid guid) const
Definition: PlayerStorage.cpp:430
uint32 GetSpell() const
Definition: TradeData.h:49
bool IsVehicle() const
Definition: Unit.h:756
Vehicle * GetVehicle() const
Definition: Unit.h:1696
Unit * GetOwner() const
Definition: Unit.cpp:10527
Pet * ToPet()
Definition: Unit.h:1740
virtual bool HasSpellCooldown(uint32) const
Definition: Unit.h:1760
ShapeshiftForm GetShapeshiftForm() const
Definition: Unit.h:1413
virtual bool HasSpellItemCooldown(uint32, uint32) const
Definition: Unit.h:1761
bool IsInDisallowedMountForm() const
Definition: Unit.cpp:21125
void CombatStart(Unit *target, bool initialAggro=true)
Definition: Unit.cpp:13547
bool HasUnitFlag2(UnitFlags2 flags) const
Definition: Unit.h:830
bool IsInSanctuary() const
Definition: Unit.h:860
virtual bool IsClass(Classes unitClass, ClassContext context=CLASS_CONTEXT_NONE) const
Definition: Unit.h:765
AuraEffect * IsScriptOverriden(SpellInfo const *spell, int32 script) const
Definition: Unit.cpp:5754
float GetCombatReach() const override
Definition: Unit.h:687
UnitFlags GetUnitFlags() const
Definition: Unit.h:823
TempSummon * ToTempSummon()
Definition: Unit.h:1742
bool HasStealthAura() const
Definition: Unit.h:1049
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:5643
std::map< uint8, AuraApplication * > VisibleAuraMap
Definition: Unit.h:652
bool IsInFlight() const
Definition: Unit.h:1019
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]
Definition: Unit.h:1478
void SendTameFailure(uint8 result)
Definition: Unit.cpp:19905
bool HasUnitMovementFlag(uint32 f) const
Definition: Unit.h:1616
virtual bool IsInWater() const
Definition: Unit.cpp:4298
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition: Unit.cpp:10474
bool isMoving() const
Definition: Unit.h:1722
ObjectGuid GetCharmGUID() const
Definition: Unit.h:1164
VisibleAuraMap const * GetVisibleAuras()
Definition: Unit.h:1493
bool IsMounted() const
Definition: Unit.h:886
Unit * GetVictim() const
Definition: Unit.h:726
bool IsCritter() const
Definition: Unit.h:1017
ObjectGuid GetOwnerGUID() const
Definition: Unit.h:1156
uint8 GetComboPoints(Unit const *who=nullptr) const
--------—Combo point system----------------—
Definition: Unit.h:1632
ObjectGuid GetCharmerGUID() const
Definition: Unit.h:1162
uint32 getTransForm() const
Definition: Unit.h:1516
virtual bool HasActivePowerType(Powers power)
Definition: Unit.h:802
void RemoveMovementImpairingAuras(bool withRoot)
Definition: Unit.cpp:5179
bool IsTotem() const
Definition: Unit.h:755
Guardian * GetGuardianPet() const
Definition: Unit.cpp:10578
ObjectGuid GetTarget() const
Definition: Unit.h:1775
bool IsInCombat() const
Definition: Unit.h:1031
ObjectGuid GetPetGUID() const
Definition: Unit.h:1166
Definition: Vehicle.h:28
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition: Vehicle.cpp:580
Definition: Group.h:169
Definition: GroupReference.h:27
GroupReference * next()
Definition: GroupReference.h:36
Definition: InstanceScript.h:142
bool isLooted() const
Definition: LootMgr.h:368
Definition: Map.h:274
bool AllowMount
Definition: Map.h:277
bool IsDungeon() const
Definition: Map.h:448
bool IsBattlegroundOrArena() const
Definition: Map.h:456
GameObject * GetGameObject(ObjectGuid const guid)
Definition: Map.cpp:3319
uint32 GetId() const
Definition: Map.h:379
Difficulty GetDifficulty() const
Definition: Map.h:443
uint32 GetRecruiterId() const
Definition: WorldSession.h:526
uint32 GetAccountId() const
Definition: WorldSession.h:361
GameObject * GetGOTarget() const
Definition: Spell.cpp:264
ObjectGuid GetItemTargetGUID() const
Definition: Spell.h:138
std::unique_ptr< PathGenerator > m_preGeneratedPath
Definition: Spell.h:776
SpellCastResult CheckSpellFocus()
Definition: Spell.cpp:7732
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition: Spell.cpp:8344
SpellCastResult CheckItems()
Definition: Spell.cpp:7164
int32 CalculateSpellDamage(uint8 i, Unit const *target) const
Definition: Spell.h:477
SpellCastResult CheckPower()
Definition: Spell.cpp:7119
SpellCastResult CheckCasterAuras(bool preventionOnly) const
Definition: Spell.cpp:6836
SpellCastResult CallScriptCheckCastHandlers()
Definition: Spell.cpp:8543
bool IsTriggered() const
Definition: Spell.h:552
SpellCastResult CheckRange(bool strict)
Definition: Spell.cpp:7033
bool HasGlobalCooldown() const
Definition: Spell.cpp:8815
Definition: SpellInfo.h:249
int32 MiscValue
Definition: SpellInfo.h:263
uint32 ApplyAuraName
Definition: SpellInfo.h:254
uint32 PreventionType
Definition: SpellInfo.h:390
uint32 CasterAuraSpell
Definition: SpellInfo.h:343
SpellCastResult CheckShapeshift(uint32 form) const
Definition: SpellInfo.cpp:1433
uint32 Mechanic
Definition: SpellInfo.h:323
uint32 GetDispelMask() const
Definition: SpellInfo.cpp:2040
uint32 GetRecoveryTime() const
Definition: SpellInfo.cpp:2395
bool IsSelfCast() const
Definition: SpellInfo.cpp:1089
uint32 CasterAuraState
Definition: SpellInfo.h:339
bool CanBeUsedInCombat() const
Definition: SpellInfo.cpp:1231
uint32 CasterAuraStateNot
Definition: SpellInfo.h:341
SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player *player=nullptr, bool strict=true) const
Definition: SpellInfo.cpp:1488
SpellSchoolMask GetSchoolMask() const
Definition: SpellInfo.cpp:1986
int32 AreaGroupId
Definition: SpellInfo.h:391
float GetMaxRange(bool positive=false, Unit *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2322
uint32 GetExplicitTargetMask() const
Definition: SpellInfo.cpp:2054
bool NeedsExplicitUnitTarget() const
Definition: SpellInfo.cpp:1032
uint32 ExcludeCasterAuraSpell
Definition: SpellInfo.h:345
uint32 SpellFamilyName
Definition: SpellInfo.h:387
uint32 AuraInterruptFlags
Definition: SpellInfo.h:353
SpellCastResult CheckExplicitTarget(Unit const *caster, WorldObject const *target, Item const *itemTarget=nullptr) const
Definition: SpellInfo.cpp:1936
Definition: DBCStructure.h:519
Definition: DBCStructure.h:1021
Definition: DBCStructure.h:1325
bool IsDungeon() const
Definition: DBCStructure.h:1351
Definition: DBCStructure.h:1817
uint32 flags1
Definition: DBCStructure.h:1822
Definition: DBCStructure.h:1909
uint32 Category
Definition: DBCStructure.h:1911
Definition: DBCStructure.h:2064
uint32 m_flags
Definition: DBCStructure.h:2066

References InstanceTemplate::AllowMount, SpellEffectInfo::ApplyAuraName, AREA_FLAG_NO_FLY_ZONE, SpellInfo::AreaGroupId, AURA_INTERRUPT_FLAG_MOUNT, AURA_INTERRUPT_FLAG_NOT_SEATED, SpellInfo::AuraInterruptFlags, CalculateSpellDamage(), CallScriptCheckCastHandlers(), SpellInfo::CanBeUsedInCombat(), Battlefield::CanFlyIn(), CanOpenLock(), Player::CanTameExoticPets(), Player::CanUseBattlegroundObject(), SpellInfo::CasterAuraSpell, SpellInfo::CasterAuraState, SpellInfo::CasterAuraStateNot, SummonPropertiesEntry::Category, CheckCasterAuras(), SpellInfo::CheckExplicitTarget(), CheckItems(), SpellInfo::CheckLocation(), CheckPower(), CheckRange(), SpellInfo::CheckShapeshift(), CheckSpellFocus(), SpellInfo::CheckTarget(), CLASS_CONTEXT_PET, CLASS_WARLOCK, Unit::CombatStart(), CONDITION_SOURCE_TYPE_SPELL, Condition::ConditionTarget, PetStable::CurrentPet, damage, Player::duel, EFFECT_0, SpellInfo::Effects, Condition::ErrorTextId, Condition::ErrorType, SpellInfo::ExcludeCasterAuraSpell, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), SpellShapeshiftFormEntry::flags1, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_TRAP, WorldSession::GetAccountId(), WorldObject::GetAreaId(), Unit::GetAuraEffectsByType(), Player::GetBattleground(), Unit::GetCharm(), Unit::GetCharmerGUID(), Unit::GetCharmGUID(), Unit::GetCombatReach(), Unit::GetComboPoints(), Creature::GetCreatureTemplate(), Pet::GetCurrentFoodBenefitLevel(), Map::GetDifficulty(), SpellInfo::GetDispelMask(), WorldObject::GetDistance(), SpellCastTargets::GetDstPos(), Object::GetEntry(), SpellInfo::GetExplicitTargetMask(), Map::GetGameObject(), GameTime::GetGameTime(), GameObject::GetGOInfo(), SpellCastTargets::GetGOTarget(), Player::GetGroup(), Unit::GetGuardianPet(), Map::GetId(), WorldObject::GetInstanceScript(), Player::GetItemByGuid(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetGUID(), Player::GetLastPotionId(), Unit::GetLevel(), Pet::GetLoadPetInfo(), WorldObject::GetMap(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellCastTargets::GetObjectTarget(), Pet::GetOwner(), Player::GetPet(), Unit::GetPetGUID(), Player::GetPetStable(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), ObjectGuid::GetRawValue(), SpellInfo::GetRecoveryTime(), WorldSession::GetRecruiterId(), CreatureTemplate::GetRequiredLootSkill(), SpellInfo::GetSchoolMask(), Vehicle::GetSeatForPassenger(), Player::GetSession(), Unit::GetShapeshiftForm(), Player::GetSkillValue(), TradeData::GetSpell(), Player::GetSummonExpireTimer(), Unit::GetTarget(), SpellCastTargets::GetTargetMask(), Item::GetTemplate(), Player::GetTradeData(), Unit::getTransForm(), Object::GetTypeId(), Unit::GetUnitFlags(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicle(), Unit::GetVictim(), WorldObject::GetVisibilityRange(), Unit::GetVisibleAuras(), WorldObject::GetZoneAndAreaId(), WorldObject::GetZoneId(), GO_STATE_READY, Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasGlobalCooldown(), Player::HasPlayerFlag(), Player::HasSpellCooldown(), Unit::HasSpellCooldown(), Unit::HasSpellItemCooldown(), Unit::HasStealthAura(), HasTriggeredCastFlag(), Unit::HasUnitFlag2(), Unit::HasUnitMovementFlag(), Unit::HasUnitState(), Pet::HaveInDiet(), HUNTER_PET, SpellInfo::Id, IMMUNITY_MECHANIC, IN_MILLISECONDS, Player::InBattleground(), ItemTemplate::InventoryType, INVTYPE_RELIC, irand(), Unit::IsAlive(), IsAutoRepeat(), Map::IsBattlegroundOrArena(), Unit::IsClass(), SpellInfo::IsCooldownStartedOnEvent(), Unit::IsCritter(), Map::IsDungeon(), MapEntry::IsDungeon(), Unit::IsFriendlyTo(), Player::IsGameMaster(), ObjectGuid::IsGameObject(), Unit::IsInCombat(), Unit::IsInDisallowedMountForm(), Unit::IsInFlight(), Player::IsInSameRaidWith(), Unit::IsInSanctuary(), Unit::IsInWater(), Item::IsLocked(), Loot::isLooted(), Unit::IsMounted(), Unit::isMoving(), IsNextMeleeSwingSpell(), WorldObject::IsOutdoors(), SpellInfo::IsPassive(), DisableMgr::IsPathfindingEnabled(), SpellInfo::IsPositive(), Item::IsPotion(), Unit::IsScriptOverriden(), SpellInfo::IsSelfCast(), Creature::IsSpellProhibited(), CreatureTemplate::IsTameable(), Unit::IsTotem(), IsTriggered(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), ItemTemplate::ItemLevel, LINEOFSIGHT_ALL_CHECKS, ItemTemplate::LockID, Creature::loot, VMAP::M2, m_caster, m_CastItem, m_customError, VehicleSeatEntry::m_flags, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_preGeneratedPath, m_selfContainer, m_spellFlags, Unit::m_spellImmune, m_spellInfo, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, ConditionSourceInfo::mConditionTargets, SpellInfo::Mechanic, MINUTE, SpellEffectInfo::MiscValue, ConditionSourceInfo::mLastFailedCondition, MOVEMENTFLAG_FALLING_FAR, SpellInfo::NeedsExplicitUnitTarget(), GroupReference::next(), PATHFIND_INCOMPLETE, PATHFIND_NOPATH, PATHFIND_SHORT, PET_TAME_CANT_CONTROL_EXOTIC, PET_TAME_DEAD, PET_TAME_NOPET_AVAILABLE, PLAYER_ALLOW_ONLY_ABILITY, POWER_MANA, SpellInfo::PreventionType, Unit::RemoveMovementImpairingAuras(), sAreaTableStore, Player::Satisfy(), sBattlefieldMgr, sConditionMgr, Unit::SendTameFailure(), sGlyphPropertiesStore, SKILL_HERBALISM, SKILL_LOCKPICKING, SKILL_MINING, SKILL_NONE, sMapStore, sObjectMgr, SPECTATOR_SPELL_BINDSIGHT, SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD, SPELL_ATTR0_ALLOW_WHILE_MOUNTED, SPELL_ATTR0_AURA_IS_DEBUFF, SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET, SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR0_ONLY_INDOORS, SPELL_ATTR0_ONLY_OUTDOORS, SPELL_ATTR0_ONLY_STEALTHED, SPELL_ATTR0_PASSIVE, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR1_INITIATE_COMBAT, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_ATTR3_ONLY_BATTLEGROUNDS, SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS, SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND, SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT, SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE, SPELL_ATTR7_DEBUG_SPELL, SPELL_AURA_ABILITY_IGNORE_AURASTATE, SPELL_AURA_AOE_CHARM, SPELL_AURA_BLOCK_SPELL_FAMILY, SPELL_AURA_DUMMY, SPELL_AURA_FLY, SPELL_AURA_HOVER, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_IGNORE_SHAPESHIFT, SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_AURA_MOD_SHAPESHIFT, SPELL_AURA_MOUNTED, SPELL_AURA_PERIODIC_MANA_LEECH, SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS, SPELL_CAST_OK, SPELL_CUSTOM_ERROR_GM_ONLY, SPELL_EFFECT_APPLY_GLYPH, SPELL_EFFECT_CHARGE, SPELL_EFFECT_CREATE_TAMED_PET, SPELL_EFFECT_DISPEL, SPELL_EFFECT_FEED_PET, SPELL_EFFECT_JUMP, SPELL_EFFECT_JUMP_DEST, SPELL_EFFECT_LEAP, SPELL_EFFECT_LEAP_BACK, SPELL_EFFECT_LEARN_PET_SPELL, SPELL_EFFECT_LEARN_SPELL, SPELL_EFFECT_OPEN_LOCK, SPELL_EFFECT_POWER_BURN, SPELL_EFFECT_POWER_DRAIN, SPELL_EFFECT_RESURRECT, SPELL_EFFECT_RESURRECT_NEW, SPELL_EFFECT_RESURRECT_PET, SPELL_EFFECT_SKINNING, SPELL_EFFECT_STEAL_BENEFICIAL_BUFF, SPELL_EFFECT_STUCK, SPELL_EFFECT_SUMMON, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_SUMMON_PLAYER, SPELL_EFFECT_SUMMON_RAF_FRIEND, SPELL_EFFECT_TALENT_SPEC_SELECT, SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER, SPELL_FAILED_AFFECTING_COMBAT, SPELL_FAILED_ALREADY_HAVE_CHARM, SPELL_FAILED_ALREADY_HAVE_SUMMON, SPELL_FAILED_ALREADY_OPEN, SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_BE_CHARMED, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_CASTER_DEAD, SPELL_FAILED_CHARMED, SPELL_FAILED_CUSTOM_ERROR, SPELL_FAILED_DAMAGE_IMMUNE, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_FOOD_LOWLEVEL, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_ITEM_ALREADY_ENCHANTED, SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_LOW_CASTLEVEL, SPELL_FAILED_LOWLEVEL, SPELL_FAILED_MOVING, SPELL_FAILED_NO_COMBO_POINTS, SPELL_FAILED_NO_MOUNTS_ALLOWED, SPELL_FAILED_NO_PET, SPELL_FAILED_NOPATH, SPELL_FAILED_NOT_BEHIND, SPELL_FAILED_NOT_HERE, SPELL_FAILED_NOT_IN_ARENA, SPELL_FAILED_NOT_IN_BATTLEGROUND, SPELL_FAILED_NOT_INFRONT, SPELL_FAILED_NOT_KNOWN, SPELL_FAILED_NOT_MOUNTED, SPELL_FAILED_NOT_ON_MOUNTED, SPELL_FAILED_NOT_ON_TAXI, SPELL_FAILED_NOT_READY, SPELL_FAILED_NOT_SHAPESHIFT, SPELL_FAILED_NOT_TRADING, SPELL_FAILED_NOTHING_TO_DISPEL, SPELL_FAILED_NOTHING_TO_STEAL, SPELL_FAILED_ONLY_ABOVEWATER, SPELL_FAILED_ONLY_BATTLEGROUNDS, SPELL_FAILED_ONLY_INDOORS, SPELL_FAILED_ONLY_OUTDOORS, SPELL_FAILED_ONLY_STEALTHED, SPELL_FAILED_ROOTED, SPELL_FAILED_SPELL_IN_PROGRESS, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_SUMMON_PENDING, SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED, SPELL_FAILED_TARGET_FRIENDLY, SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED, SPELL_FAILED_TARGET_NOT_IN_INSTANCE, SPELL_FAILED_TARGET_NOT_LOOTED, SPELL_FAILED_TARGET_UNSKINNABLE, SPELL_FAILED_TRY_AGAIN, SPELL_FAILED_UNIQUE_GLYPH, SPELL_FAILED_WRONG_PET_FOOD, SPELL_FLAG_REDIRECTED, SPELL_PREVENTION_TYPE_NONE, SPELL_RELIC_COOLDOWN, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyName, TriggeredByAuraSpellData::spellInfo, SpellInfo::SpellLevel, sScriptMgr, sSpellMgr, sSpellShapeshiftFormStore, sSummonPropertiesStore, STATUS_IN_PROGRESS, STATUS_WAIT_LEAVE, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, TARGET_FLAG_ITEM, TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT_ENEMY, TARGET_GAMEOBJECT_ITEM_TARGET, TARGET_GAMEOBJECT_TARGET, TARGET_UNIT_PET, Object::ToCreature(), Unit::ToPet(), Object::ToPlayer(), Unit::ToTempSummon(), Object::ToUnit(), TRADE_SLOT_NONTRADED, TRIGGERED_IGNORE_CASTER_AURAS, TRIGGERED_IGNORE_CASTER_AURASTATE, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE, TRIGGERED_IGNORE_EFFECTS, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SHAPESHIFT, TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD, GameObjectTemplate::type, TYPEID_PLAYER, TYPEID_UNIT, UNIT_FLAG2_ALLOW_CHEAT_SPELLS, UNIT_FLAG_SKINNABLE, UNIT_STATE_CHARGING, UNIT_STATE_ROOT, unitTarget, PetStable::UnslottedPets, VEHICLE_SEAT_FLAG_CAN_ATTACK, VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL, VEHICLE_SEAT_FLAG_UNCONTROLLED, and WORLD_TRIGGER.

Referenced by _cast(), Unit::_UpdateAutoRepeatSpell(), Unit::AttackerStateUpdate(), Player::CastItemUseSpell(), CheckPetCast(), WorldSession::HandleAcceptTradeOpcode(), prepare(), and go_wind_stone::go_wind_stoneAI::SummonNPC().

◆ CheckCasterAuras()

SpellCastResult Spell::CheckCasterAuras ( bool  preventionOnly) const
6837{
6838 // spells totally immuned to caster auras (wsg flag drop, give marks etc)
6840 return SPELL_CAST_OK;
6841
6842 uint8 school_immune = 0;
6843 uint32 mechanic_immune = 0;
6844 uint32 dispel_immune = 0;
6845
6846 // Check if the spell grants school or mechanic immunity.
6847 // We use bitmasks so the loop is done only once and not on every aura check below.
6849 {
6850 for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
6851 {
6852 if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY)
6853 school_immune |= uint32(m_spellInfo->Effects[i].MiscValue);
6854 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY)
6855 mechanic_immune |= 1 << uint32(m_spellInfo->Effects[i].MiscValue);
6856 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY)
6857 dispel_immune |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6858 }
6859 // immune movement impairment and loss of control
6860 // PVP trinket EMFH TOC PVP trinket Bullheaded Bestial Wrath // Beath Within // Medalion of Immunity
6861 if (m_spellInfo->Id == 42292 || m_spellInfo->Id == 59752 || m_spellInfo->Id == 65547 || m_spellInfo->Id == 53490 || m_spellInfo->Id == 19574 || m_spellInfo->Id == 34471 || m_spellInfo->Id == 46227)
6863 }
6864
6866
6867 // Glyph of Pain Suppression
6868 // there is no other way to handle it
6869 if (m_spellInfo->Id == 33206 && !m_caster->HasAura(63248))
6870 usableInStun = false;
6871
6872 // Check whether the cast should be prevented by any state you might have.
6873 SpellCastResult prevented_reason = SPELL_CAST_OK;
6874 // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
6875 uint32 unitflag = m_caster->GetUnitFlags(); // Get unit state
6876
6877 // Xinef: if spell is triggered check preventionType only
6878 if (!preventionOnly)
6879 {
6880 if (unitflag & UNIT_FLAG_STUNNED)
6881 {
6882 // spell is usable while stunned, check if caster has only mechanic stun auras, another stun types must prevent cast spell
6883 if (usableInStun)
6884 {
6885 bool foundNotStun = false;
6886 uint32 mask = (1 << MECHANIC_STUN) | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_HORROR);
6887 // Barkskin should skip sleep effects, sap and fears
6888 if (m_spellInfo->Id == 22812)
6889 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6890 // Hand of Freedom, can be used while sapped
6891 if (m_spellInfo->Id == 1044)
6892 mask |= 1 << MECHANIC_SAPPED;
6894 for (Unit::AuraEffectList::const_iterator i = stunAuras.begin(); i != stunAuras.end(); ++i)
6895 {
6896 if ((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() && !((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() & mask))
6897 {
6898 foundNotStun = true;
6899 break;
6900 }
6901 }
6902 if (foundNotStun)
6903 prevented_reason = SPELL_FAILED_STUNNED;
6904 }
6905 else
6906 prevented_reason = SPELL_FAILED_STUNNED;
6907 }
6909 prevented_reason = SPELL_FAILED_CONFUSED;
6911 prevented_reason = SPELL_FAILED_FLEEING;
6912 }
6913
6914 // Xinef: if there is no prevented_reason, check prevention types
6915 if (prevented_reason == SPELL_CAST_OK)
6916 {
6918 prevented_reason = SPELL_FAILED_SILENCED;
6920 prevented_reason = SPELL_FAILED_PACIFIED;
6921 }
6922
6923 // Attr must make flag drop spell totally immune from all effects
6924 if (prevented_reason != SPELL_CAST_OK)
6925 {
6926 if (school_immune || mechanic_immune || dispel_immune)
6927 {
6928 //Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
6930 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
6931 {
6932 Aura const* aura = itr->second->GetBase();
6933 SpellInfo const* auraInfo = aura->GetSpellInfo();
6934 if (auraInfo->GetAllEffectsMechanicMask() & mechanic_immune)
6935 continue;
6936 if (auraInfo->GetSchoolMask() & school_immune && !auraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS))
6937 continue;
6938 if (auraInfo->GetDispelMask() & dispel_immune)
6939 continue;
6940
6941 //Make a second check for spell failed so the right SPELL_FAILED message is returned.
6942 //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
6943 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6944 {
6945 if (AuraEffect* part = aura->GetEffect(i))
6946 {
6947 switch (part->GetAuraType())
6948 {
6950 {
6951 uint32 mask = 1 << MECHANIC_STUN;
6952 // Barkskin should skip sleep effects, sap and fears
6953 if (m_spellInfo->Id == 22812)
6954 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6955 // Hand of Freedom, can be used while sapped
6956 if (m_spellInfo->Id == 1044)
6957 mask |= 1 << MECHANIC_SAPPED;
6958
6959 if (!usableInStun || !(auraInfo->GetAllEffectsMechanicMask() & mask))
6960 return SPELL_FAILED_STUNNED;
6961 break;
6962 }
6965 return SPELL_FAILED_CONFUSED;
6966 break;
6969 return SPELL_FAILED_FLEEING;
6970 break;
6975 return SPELL_FAILED_PACIFIED;
6977 return SPELL_FAILED_SILENCED;
6978 break;
6979 default:
6980 break;
6981 }
6982 }
6983 }
6984 }
6985 }
6986 // You are prevented from casting and the spell casted does not grant immunity. Return a failed error.
6987 else
6988 return prevented_reason;
6989 }
6990 return SPELL_CAST_OK;
6991}
@ UNIT_FLAG_STUNNED
Definition: UnitDefines.h:247
@ UNIT_FLAG_PACIFIED
Definition: UnitDefines.h:246
@ UNIT_FLAG_CONFUSED
Definition: UnitDefines.h:251
@ UNIT_FLAG_FLEEING
Definition: UnitDefines.h:252
@ UNIT_FLAG_SILENCED
Definition: UnitDefines.h:242
@ SPELL_AURA_DISPEL_IMMUNITY
Definition: SpellAuraDefines.h:104
@ SPELL_AURA_MOD_FEAR
Definition: SpellAuraDefines.h:70
@ SPELL_AURA_MOD_PACIFY
Definition: SpellAuraDefines.h:88
@ SPELL_AURA_MOD_SILENCE
Definition: SpellAuraDefines.h:90
@ SPELL_AURA_SCHOOL_IMMUNITY
Definition: SpellAuraDefines.h:102
@ SPELL_AURA_MECHANIC_IMMUNITY
Definition: SpellAuraDefines.h:140
@ SPELL_AURA_MOD_PACIFY_SILENCE
Definition: SpellAuraDefines.h:123
@ SPELL_AURA_MOD_CONFUSE
Definition: SpellAuraDefines.h:68
@ SPELL_AURA_MOD_STUN
Definition: SpellAuraDefines.h:75
@ SPELL_PREVENTION_TYPE_SILENCE
Definition: SharedDefines.h:1554
@ SPELL_PREVENTION_TYPE_PACIFY
Definition: SharedDefines.h:1555
@ SPELL_ATTR5_ALLOW_WHILE_STUNNED
Definition: SharedDefines.h:570
@ SPELL_ATTR5_ALLOW_WHILE_FLEEING
Definition: SharedDefines.h:584
@ SPELL_ATTR5_ALLOW_WHILE_CONFUSED
Definition: SharedDefines.h:585
@ SPELL_ATTR1_IMMUNITY_PURGES_EFFECT
Definition: SharedDefines.h:434
@ SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS
Definition: SharedDefines.h:435
@ MECHANIC_STUN
Definition: SharedDefines.h:1337
@ MECHANIC_FREEZE
Definition: SharedDefines.h:1338
@ MECHANIC_SLEEP
Definition: SharedDefines.h:1335
@ MECHANIC_SAPPED
Definition: SharedDefines.h:1355
@ MECHANIC_HORROR
Definition: SharedDefines.h:1349
#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK
Definition: SharedDefines.h:1361
@ SPELL_FAILED_STUNNED
Definition: SharedDefines.h:1057
@ SPELL_FAILED_CONFUSED
Definition: SharedDefines.h:975
@ SPELL_FAILED_SILENCED
Definition: SharedDefines.h:1053
@ SPELL_FAILED_FLEEING
Definition: SharedDefines.h:983
@ SPELL_FAILED_PACIFIED
Definition: SharedDefines.h:1047
@ SPELL_ATTR6_NOT_AN_ATTACK
Definition: SharedDefines.h:606
std::multimap< uint32, AuraApplication * > AuraApplicationMap
Definition: Unit.h:639
AuraApplicationMap & GetAppliedAuras()
Definition: Unit.h:1266
Definition: SpellAuras.h:87
AuraEffect * GetEffect(uint8 effIndex) const
Definition: SpellAuras.h:175
SpellInfo const * GetSpellInfo() const
Definition: SpellAuras.h:100
uint32 GetAllEffectsMechanicMask() const
Definition: SpellInfo.cpp:1991

References SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), Unit::GetAuraEffectsByType(), SpellInfo::GetDispelMask(), Aura::GetEffect(), SpellInfo::GetSchoolMask(), Aura::GetSpellInfo(), Unit::GetUnitFlags(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK, m_caster, m_spellInfo, MAX_SPELL_EFFECTS, MECHANIC_FREEZE, MECHANIC_HORROR, MECHANIC_SAPPED, MECHANIC_SLEEP, MECHANIC_STUN, SpellInfo::PreventionType, SPELL_ATTR1_IMMUNITY_PURGES_EFFECT, SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS, SPELL_ATTR5_ALLOW_WHILE_CONFUSED, SPELL_ATTR5_ALLOW_WHILE_FLEEING, SPELL_ATTR5_ALLOW_WHILE_STUNNED, SPELL_ATTR6_NOT_AN_ATTACK, SPELL_AURA_DISPEL_IMMUNITY, SPELL_AURA_MECHANIC_IMMUNITY, SPELL_AURA_MOD_CONFUSE, SPELL_AURA_MOD_FEAR, SPELL_AURA_MOD_PACIFY, SPELL_AURA_MOD_PACIFY_SILENCE, SPELL_AURA_MOD_SILENCE, SPELL_AURA_MOD_STUN, SPELL_AURA_SCHOOL_IMMUNITY, SPELL_CAST_OK, SPELL_FAILED_CONFUSED, SPELL_FAILED_FLEEING, SPELL_FAILED_PACIFIED, SPELL_FAILED_SILENCED, SPELL_FAILED_STUNNED, SPELL_PREVENTION_TYPE_PACIFY, SPELL_PREVENTION_TYPE_SILENCE, UNIT_FLAG_CONFUSED, UNIT_FLAG_FLEEING, UNIT_FLAG_PACIFIED, UNIT_FLAG_SILENCED, and UNIT_FLAG_STUNNED.

Referenced by CheckCast().

◆ CheckDst()

void Spell::CheckDst ( )
inline
void SetDst(float x, float y, float z, float orientation, uint32 mapId=MAPID_INVALID)
Definition: Spell.cpp:406

References SpellCastTargets::HasDst(), m_caster, m_targets, and SpellCastTargets::SetDst().

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ CheckEffectExecuteData()

void Spell::CheckEffectExecuteData ( )
protected
8477{
8478 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8480}
#define ASSERT
Definition: Errors.h:68

References ASSERT, m_effectExecuteData, and MAX_SPELL_EFFECTS.

Referenced by PrepareTargetProcessing(), and ~Spell().

◆ CheckEffectTarget()

bool Spell::CheckEffectTarget ( Unit const *  target,
uint32  eff 
) const
Todo:
: below shouldn't be here, but it's temporary
7910{
7911 switch (m_spellInfo->Effects[eff].ApplyAuraName)
7912 {
7917 if (target->GetTypeId() == TYPEID_UNIT && target->IsVehicle())
7918 return false;
7919 if (target->IsMounted())
7920 return false;
7921 if (target->GetCharmerGUID())
7922 return false;
7923 if (int32 damage = CalculateSpellDamage(eff, target))
7924 if ((int32)target->GetLevel() > damage)
7925 return false;
7926 break;
7927 default:
7928 break;
7929 }
7930
7931 // xinef: skip los checking if spell has appropriate attribute, or target requires specific entry
7932 // this is only for target addition and target has to have unselectable flag, this is valid for FLAG_EXTRA_TRIGGER and quest triggers however there are some without this flag, used not_selectable
7933 if (m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) || (target->GetTypeId() == TYPEID_UNIT && target->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE) && (m_spellInfo->Effects[eff].TargetA.GetCheckType() == TARGET_CHECK_ENTRY || m_spellInfo->Effects[eff].TargetB.GetCheckType() == TARGET_CHECK_ENTRY)))
7934 return true;
7935
7936 // if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour
7939 {
7940 return true;
7941 }
7942
7944 //Check targets for LOS visibility (except spells without range limitations)
7945 switch (m_spellInfo->Effects[eff].Effect)
7946 {
7948 // player far away, maybe his corpse near?
7949 if (target != m_caster && !target->IsWithinLOSInMap(m_caster))
7950 {
7952 return false;
7953
7955 if (!corpse)
7956 return false;
7957
7958 if (target->GetGUID() != corpse->GetOwnerGUID())
7959 return false;
7960
7962 return false;
7963 }
7964 break;
7966 {
7968 {
7969 if (target->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE))
7970 return true;
7971
7972 return false;
7973 }
7974
7976 if (!corpse)
7977 return false;
7978
7979 if (target->GetGUID() != corpse->GetOwnerGUID())
7980 return false;
7981
7983 return false;
7984
7986 return false;
7987 }
7988 break;
7990 if (m_caster->GetTypeId() != TYPEID_PLAYER || target->GetTypeId() != TYPEID_PLAYER)
7991 return false;
7992 if (m_caster->ToPlayer()->GetSession()->IsARecruiter() && target->ToPlayer()->GetSession()->GetRecruiterId() != m_caster->ToPlayer()->GetSession()->GetAccountId())
7993 return false;
7994 if (m_caster->ToPlayer()->GetSession()->GetRecruiterId() != target->ToPlayer()->GetSession()->GetAccountId() && target->ToPlayer()->GetSession()->IsARecruiter())
7995 return false;
7996 if (target->ToPlayer()->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
7997 return false;
7998 break;
7999 default: // normal case
8000 {
8001 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
8002 GameObject* gobCaster = nullptr;
8004 {
8006 }
8007 else if (m_caster->GetEntry() == WORLD_TRIGGER)
8008 {
8009 if (TempSummon* tempSummon = m_caster->ToTempSummon())
8010 {
8011 gobCaster = tempSummon->GetSummonerGameObject();
8012 }
8013 }
8014
8015 if (gobCaster)
8016 {
8017 if (gobCaster->GetGOInfo()->IsIgnoringLOSChecks())
8018 {
8019 return true;
8020 }
8021
8022 // If spell casted by gameobject then ignore M2 models
8023 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
8024 }
8025
8026 if (target != m_caster)
8027 {
8028 if (m_targets.HasDst())
8029 {
8030 float x = m_targets.GetDstPos()->GetPositionX();
8031 float y = m_targets.GetDstPos()->GetPositionY();
8032 float z = m_targets.GetDstPos()->GetPositionZ();
8033
8034 if (!target->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks(losChecks)))
8035 {
8036 return false;
8037 }
8038 }
8040 {
8041 return false;
8042 }
8043 }
8044 break;
8045 }
8046 }
8047
8048 return true;
8049}
@ SPELL_DISABLE_LOS
Definition: DisableMgr.h:50
@ DISABLE_TYPE_SPELL
Definition: DisableMgr.h:29
@ CORPSE_FLAG_LOOTABLE
Definition: Corpse.h:45
@ CORPSE_FIELD_FLAGS
Definition: UpdateFields.h:427
@ UNIT_FLAG_NOT_SELECTABLE
Definition: UnitDefines.h:254
@ TARGET_CHECK_ENTRY
Definition: SpellInfo.h:115
@ CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL
Definition: IWorld.h:251
@ SPELL_EFFECT_SKIN_PLAYER_CORPSE
Definition: SharedDefines.h:894
#define sWorld
Definition: World.h:444
bool IsDisabledFor(DisableType type, uint32 entry, Unit const *unit, uint8 flags)
Definition: DisableMgr.cpp:306
Corpse * GetCorpse(WorldObject const &u, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:182
Definition: Corpse.h:49
ObjectGuid GetOwnerGUID() const
Definition: Corpse.h:68
bool IsIgnoringLOSChecks() const
Definition: GameObjectData.h:643
bool HasFlag(uint16 index, uint32 flag) const
Definition: Object.cpp:889
bool IsARecruiter() const
Definition: WorldSession.h:527
ObjectGuid GetCorpseTargetGUID() const
Definition: Spell.cpp:281

References CalculateSpellDamage(), CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL, CORPSE_FIELD_FLAGS, CORPSE_FLAG_LOOTABLE, damage, DISABLE_TYPE_SPELL, SpellInfo::Effects, WorldSession::GetAccountId(), Unit::GetCharmerGUID(), ObjectAccessor::GetCorpse(), SpellCastTargets::GetCorpseTargetGUID(), SpellCastTargets::GetDstPos(), Object::GetEntry(), Map::GetGameObject(), GameObject::GetGOInfo(), Object::GetGUID(), Unit::GetLevel(), WorldObject::GetMap(), Corpse::GetOwnerGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldSession::GetRecruiterId(), Player::GetSession(), Object::GetTypeId(), SpellInfo::HasAttribute(), SpellCastTargets::HasDst(), Object::HasFlag(), Unit::HasUnitFlag(), SpellInfo::Id, WorldSession::IsARecruiter(), DisableMgr::IsDisabledFor(), ObjectGuid::IsGameObject(), GameObjectTemplate::IsIgnoringLOSChecks(), Unit::IsMounted(), IsTriggered(), Unit::IsVehicle(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), LINEOFSIGHT_ALL_CHECKS, VMAP::M2, m_caster, m_originalCasterGUID, m_spellFlags, m_spellInfo, m_targets, m_triggeredByAuraSpell, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_AURA_AOE_CHARM, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_DISABLE_LOS, SPELL_EFFECT_RESURRECT_NEW, SPELL_EFFECT_SKIN_PLAYER_CORPSE, SPELL_EFFECT_SUMMON_RAF_FRIEND, SPELL_FLAG_REDIRECTED, TriggeredByAuraSpellData::spellInfo, sWorld, TARGET_CHECK_ENTRY, Object::ToPlayer(), Unit::ToTempSummon(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_FLAG_NOT_SELECTABLE, UNIT_FLAG_SKINNABLE, and WORLD_TRIGGER.

Referenced by AddUnitTarget().

◆ CheckItems()

SpellCastResult Spell::CheckItems ( )
Todo:
Needs review
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
7165{
7166 Player* player = m_caster->ToPlayer();
7167 if (!player)
7168 {
7169 // Non-player case: Check if creature is disarmed
7171 {
7173 }
7174
7175 return SPELL_CAST_OK;
7176 }
7177
7178 if (!m_CastItem)
7179 {
7180 if (m_castItemGUID)
7182 }
7183 else
7184 {
7185 uint32 itemid = m_CastItem->GetEntry();
7186 if (!player->HasItemCount(itemid))
7188
7189 ItemTemplate const* proto = m_CastItem->GetTemplate();
7190 if (!proto)
7192
7193 for (int i = 0; i < MAX_ITEM_SPELLS; ++i)
7194 if (proto->Spells[i].SpellCharges)
7195 if (m_CastItem->GetSpellCharges(i) == 0)
7197
7198 // consumable cast item checks
7200 {
7201 // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
7202 SpellCastResult failReason = SPELL_CAST_OK;
7203 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
7204 {
7205 // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
7206 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET)
7207 continue;
7208
7209 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL)
7210 {
7212 {
7214 continue;
7215 }
7216 else
7217 {
7218 failReason = SPELL_CAST_OK;
7219 break;
7220 }
7221 }
7222
7223 // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
7224 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
7225 {
7226 if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS))
7227 {
7229 continue;
7230 }
7231
7232 Powers power = Powers(m_spellInfo->Effects[i].MiscValue);
7234 {
7236 continue;
7237 }
7238 else
7239 {
7240 failReason = SPELL_CAST_OK;
7241 break;
7242 }
7243 }
7244 }
7245 if (failReason != SPELL_CAST_OK)
7246 return failReason;
7247 }
7248 }
7249
7250 // check target item
7252 {
7255
7256 if (!m_targets.GetItemTarget())
7258
7261 }
7262 // if not item target then required item must be equipped
7263 else
7264 {
7265 // Xinef: this is not true in my opinion, in eg bladestorm will not be canceled after disarm
7266 //if (!HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT))
7269 }
7270
7271 // do not take reagents for these item casts
7273 {
7275 // Not own traded item (in trader trade slot) requires reagents even if triggered spell
7276 if (!checkReagents)
7277 if (Item* targetItem = m_targets.GetItemTarget())
7278 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
7279 checkReagents = true;
7280
7281 // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
7282 if (checkReagents)
7283 {
7284 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
7285 {
7286 if (m_spellInfo->Reagent[i] <= 0)
7287 continue;
7288
7289 uint32 itemid = m_spellInfo->Reagent[i];
7290 uint32 itemcount = m_spellInfo->ReagentCount[i];
7291
7292 // if CastItem is also spell reagent
7293 if (m_CastItem && m_CastItem->GetEntry() == itemid)
7294 {
7295 ItemTemplate const* proto = m_CastItem->GetTemplate();
7296 if (!proto)
7298 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
7299 {
7300 // CastItem will be used up and does not count as reagent
7301 int32 charges = m_CastItem->GetSpellCharges(s);
7302 if (proto->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
7303 {
7304 ++itemcount;
7305 break;
7306 }
7307 }
7308 }
7309 if (!player->HasItemCount(itemid, itemcount))
7310 return SPELL_FAILED_REAGENTS;
7311 }
7312 }
7313
7314 // check totem-item requirements (items presence in inventory)
7315 uint32 totems = 2;
7316 for (int i = 0; i < 2; ++i)
7317 {
7318 if (m_spellInfo->Totem[i] != 0)
7319 {
7320 if (player->HasItemCount(m_spellInfo->Totem[i]))
7321 {
7322 totems -= 1;
7323 continue;
7324 }
7325 }
7326 else
7327 totems -= 1;
7328 }
7329 if (totems != 0)
7330 return SPELL_FAILED_TOTEMS; //0x7C
7331
7332 // Check items for TotemCategory (items presence in inventory)
7334 for (int i = 0; i < 2; ++i)
7335 {
7336 if (m_spellInfo->TotemCategory[i] != 0)
7337 {
7339 {
7340 TotemCategory -= 1;
7341 continue;
7342 }
7343 }
7344 else
7345 TotemCategory -= 1;
7346 }
7347 if (TotemCategory != 0)
7348 return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
7349 }
7350
7351 // special checks for spell effects
7352 for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
7353 {
7354 switch (m_spellInfo->Effects[i].Effect)
7355 {
7358 {
7359 // m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
7360 Unit* target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : player;
7361 if (target->GetTypeId() == TYPEID_PLAYER && !IsTriggered())
7362 {
7363 // SPELL_EFFECT_CREATE_ITEM_2 differs from SPELL_EFFECT_CREATE_ITEM in that it picks the random item to create from a pool of potential items,
7364 // so we need to make sure there is at least one free space in the player's inventory
7366 if (target->ToPlayer()->GetFreeInventorySpace() == 0)
7367 {
7368 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7370 }
7371
7372 if (m_spellInfo->Effects[i].ItemType)
7373 {
7374 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType);
7375 if (!itemTemplate)
7377
7378 uint32 createCount = std::clamp<uint32>(m_spellInfo->Effects[i].CalcValue(), 1u, itemTemplate->GetMaxStackSize());
7379 ItemPosCountVec dest;
7380 InventoryResult msg = target->ToPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, createCount);
7381 if (msg != EQUIP_ERR_OK)
7382 {
7384 if (!itemTemplate->ItemLimitCategory)
7385 {
7386 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7388 }
7389 else
7390 {
7391 // Conjure Food/Water/Refreshment spells
7394 else if (!(target->ToPlayer()->HasItemCount(m_spellInfo->Effects[i].ItemType)))
7395 {
7396 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7398 }
7399 else
7400 player->CastSpell(player, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere
7401
7403 }
7404 }
7405 }
7406 }
7407 break;
7408 }
7410 {
7411 if (player->GetFreeInventorySpace() == 0)
7412 {
7413 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7415 }
7416 break;
7417 }
7419 if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
7421 {
7422 // cannot enchant vellum for other player
7425 // do not allow to enchant vellum from scroll made by vellum-prevent exploit
7428 ItemPosCountVec dest;
7429 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
7430 if (msg != EQUIP_ERR_OK)
7431 {
7432 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7434 }
7435 }
7436 [[fallthrough]];
7438 {
7439 Item* targetItem = m_targets.GetItemTarget();
7440 if (!targetItem)
7442
7443 // xinef: required level has to be checked also! Exploit fix
7444 if (targetItem->GetTemplate()->ItemLevel < m_spellInfo->BaseLevel || (targetItem->GetTemplate()->RequiredLevel && targetItem->GetTemplate()->RequiredLevel < m_spellInfo->BaseLevel))
7445 return SPELL_FAILED_LOWLEVEL;
7446
7447 bool isItemUsable = false;
7448 for (uint8 e = 0; e < MAX_ITEM_PROTO_SPELLS; ++e)
7449 {
7450 ItemTemplate const* proto = targetItem->GetTemplate();
7451 if (proto->Spells[e].SpellId && (
7454 {
7455 isItemUsable = true;
7456 break;
7457 }
7458 }
7459
7460 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue);
7461 // do not allow adding usable enchantments to items that have use effect already
7462 if (enchantEntry)
7463 {
7464 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
7465 {
7466 switch (enchantEntry->type[s])
7467 {
7469 if (isItemUsable)
7471 break;
7473 {
7474 uint32 numSockets = 0;
7475 for (uint32 socket = 0; socket < MAX_ITEM_PROTO_SOCKETS; ++socket)
7476 if (targetItem->GetTemplate()->Socket[socket].Color)
7477 ++numSockets;
7478
7479 if (numSockets == MAX_ITEM_PROTO_SOCKETS || targetItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
7481 break;
7482 }
7483 }
7484 }
7485 }
7486
7487 // Not allow enchant in trade slot for some enchant type
7488 if (targetItem->GetOwner() != m_caster)
7489 {
7490 if (!enchantEntry)
7491 return SPELL_FAILED_ERROR;
7492 if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
7494 }
7495 break;
7496 }
7498 {
7499 Item* item = m_targets.GetItemTarget();
7500 if (!item)
7502 // Not allow enchant in trade slot for some enchant type
7503 if (item->GetOwner() != m_caster)
7504 {
7505 uint32 enchant_id = m_spellInfo->Effects[i].MiscValue;
7506 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
7507 if (!pEnchant)
7508 return SPELL_FAILED_ERROR;
7509 if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND)
7511 }
7512
7513 // Xinef: Apply item level restriction if the enchanting spell has max level restrition set
7514 if (m_CastItem && m_spellInfo->MaxLevel > 0)
7515 {
7517 return SPELL_FAILED_LOWLEVEL;
7518 if (item->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel)
7520 }
7521
7522 break;
7523 }
7525 // check item existence in effect code (not output errors at offhand hold item effect to main hand for example
7526 break;
7528 {
7529 if (!m_targets.GetItemTarget())
7531
7532 // prevent disenchanting in trade slot
7535
7536 ItemTemplate const* itemProto = m_targets.GetItemTarget()->GetTemplate();
7537 if (!itemProto)
7539
7540 uint32 item_quality = itemProto->Quality;
7541 // 2.0.x addon: Check player enchanting level against the item disenchanting requirements
7542 uint32 item_disenchantskilllevel = itemProto->RequiredDisenchantSkill;
7543 if (item_disenchantskilllevel == uint32(-1))
7545 if (item_disenchantskilllevel > player->GetSkillValue(SKILL_ENCHANTING))
7547 if (item_quality > 4 || item_quality < 2)
7549 if (itemProto->Class != ITEM_CLASS_WEAPON && itemProto->Class != ITEM_CLASS_ARMOR)
7551 if (!itemProto->DisenchantID)
7553 break;
7554 }
7556 {
7557 if (!m_targets.GetItemTarget())
7559 //ensure item is a prospectable ore
7562 //prevent prospecting in trade slot
7565 //Check for enough skill in jewelcrafting
7566 uint32 item_prospectingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7567 if (item_prospectingskilllevel > player->GetSkillValue(SKILL_JEWELCRAFTING))
7569 //make sure the player has the required ores in inventory
7570 if (m_targets.GetItemTarget()->GetCount() < 5)
7572
7575
7576 break;
7577 }
7579 {
7580 if (!m_targets.GetItemTarget())
7582 //ensure item is a millable herb
7585 //prevent milling in trade slot
7588 //Check for enough skill in inscription
7589 uint32 item_millingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7590 if (item_millingskilllevel > player->GetSkillValue(SKILL_INSCRIPTION))
7592 //make sure the player has the required herbs in inventory
7593 if (m_targets.GetItemTarget()->GetCount() < 5)
7595
7598
7599 break;
7600 }
7603 {
7606
7608 break;
7609
7611 if (!pItem || pItem->IsBroken())
7613
7614 switch (pItem->GetTemplate()->SubClass)
7615 {
7617 {
7618 uint32 ammo = pItem->GetEntry();
7619 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7620 return SPELL_FAILED_NO_AMMO;
7621 };
7622 break;
7626 {
7628 if (!ammo)
7629 {
7630 // Requires No Ammo
7631 if (m_caster->HasAura(46699))
7632 break; // skip other checks
7633
7634 return SPELL_FAILED_NO_AMMO;
7635 }
7636
7637 ItemTemplate const* ammoProto = sObjectMgr->GetItemTemplate(ammo);
7638 if (!ammoProto)
7639 return SPELL_FAILED_NO_AMMO;
7640
7641 if (ammoProto->Class != ITEM_CLASS_PROJECTILE)
7642 return SPELL_FAILED_NO_AMMO;
7643
7644 // check ammo ws. weapon compatibility
7645 switch (pItem->GetTemplate()->SubClass)
7646 {
7649 if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW)
7650 return SPELL_FAILED_NO_AMMO;
7651 break;
7653 if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET)
7654 return SPELL_FAILED_NO_AMMO;
7655 break;
7656 default:
7657 return SPELL_FAILED_NO_AMMO;
7658 }
7659
7660 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7661 {
7663 return SPELL_FAILED_NO_AMMO;
7664 }
7665 };
7666 break;
7668 break;
7669 default:
7670 break;
7671 }
7672 break;
7673 }
7675 {
7676 uint32 item_id = m_spellInfo->Effects[i].ItemType;
7677 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
7678
7679 if (!pProto)
7681
7682 if (Item* pitem = player->GetItemByEntry(item_id))
7683 {
7684 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
7685 if (pProto->Spells[x].SpellCharges != 0 && pitem->GetSpellCharges(x) == pProto->Spells[x].SpellCharges)
7687 }
7688 break;
7689 }
7690 default:
7691 break;
7692 }
7693 }
7694
7695 // check weapon presence in slots for main/offhand weapons
7696 if (/*never skip those checks !HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) &&*/ m_spellInfo->EquippedItemClass >= 0)
7697 {
7698 // main hand weapon required
7700 {
7702
7703 // skip spell if no weapon in slot or broken
7704 if (!item || item->IsBroken())
7706
7707 // skip spell if weapon not fit to triggered spell
7710 }
7711
7712 // offhand hand weapon required
7714 {
7716
7717 // skip spell if no weapon in slot or broken
7718 if (!item || item->IsBroken())
7720
7721 // skip spell if weapon not fit to triggered spell
7724 }
7725
7727 }
7728
7729 return SPELL_CAST_OK;
7730}
std::int8_t int8
Definition: Define.h:105
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
InventoryResult
Definition: Item.h:46
@ EQUIP_ERR_OK
Definition: Item.h:47
@ EQUIP_ERR_INVENTORY_FULL
Definition: Item.h:97
#define MAX_ITEM_SPELLS
Definition: Item.h:215
@ ENCHANTMENT_CAN_SOULBOUND
Definition: Item.h:201
@ NULL_BAG
Definition: Item.h:40
@ NULL_SLOT
Definition: Item.h:41
@ PRISMATIC_ENCHANTMENT_SLOT
Definition: Item.h:175
@ ITEM_SUBCLASS_WEAPON_CROSSBOW
Definition: ItemTemplate.h:370
@ ITEM_SUBCLASS_WEAPON_GUN
Definition: ItemTemplate.h:355
@ ITEM_SUBCLASS_WEAPON_BOW
Definition: ItemTemplate.h:354
@ ITEM_SUBCLASS_WEAPON_WAND
Definition: ItemTemplate.h:371
@ ITEM_SUBCLASS_WEAPON_THROWN
Definition: ItemTemplate.h:368
@ ITEM_SPELLTRIGGER_ON_USE
Definition: ItemTemplate.h:77
@ ITEM_SPELLTRIGGER_ON_NO_DELAY_USE
Definition: ItemTemplate.h:87
@ ITEM_FLAG_IS_MILLABLE
Definition: ItemTemplate.h:176
@ ITEM_FLAG_NO_REAGENT_COST
Definition: ItemTemplate.h:175
@ ITEM_FLAG_IS_PROSPECTABLE
Definition: ItemTemplate.h:165
@ ITEM_SUBCLASS_ARROW
Definition: ItemTemplate.h:424
@ ITEM_SUBCLASS_BULLET
Definition: ItemTemplate.h:425
#define MAX_ITEM_PROTO_SOCKETS
Definition: ItemTemplate.h:622
#define MAX_ITEM_PROTO_SPELLS
Definition: ItemTemplate.h:623
@ ITEM_CLASS_PROJECTILE
Definition: ItemTemplate.h:305
@ ITEM_CLASS_ARMOR
Definition: ItemTemplate.h:303
@ ITEM_CLASS_WEAPON
Definition: ItemTemplate.h:301
@ ITEM_CLASS_CONSUMABLE
Definition: ItemTemplate.h:299
@ PLAYER_AMMO_ID
Definition: UpdateFields.h:369
std::vector< ItemPosCount > ItemPosCountVec
Definition: Player.h:771
LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true)
LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true)
@ ITEM_ENCHANTMENT_TYPE_USE_SPELL
Definition: DBCEnums.h:373
@ ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET
Definition: DBCEnums.h:374
#define MAX_SPELL_REAGENTS
Definition: DBCStructure.h:1639
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition: DBCStructure.h:1838
@ EFFECT_1
Definition: SharedDefines.h:32
@ MAX_POWERS
Definition: SharedDefines.h:276
@ SPELL_EFFECT_DISENCHANT
Definition: SharedDefines.h:877
@ SPELL_EFFECT_PROSPECTING
Definition: SharedDefines.h:905
@ SPELL_EFFECT_ENCHANT_HELD_ITEM
Definition: SharedDefines.h:870
@ SPELL_EFFECT_ENCHANT_ITEM
Definition: SharedDefines.h:831
@ SPELL_EFFECT_WEAPON_DAMAGE
Definition: SharedDefines.h:836
@ SPELL_EFFECT_HEAL
Definition: SharedDefines.h:788
@ SPELL_EFFECT_MILLING
Definition: SharedDefines.h:936
@ SPELL_EFFECT_CREATE_MANA_GEM
Definition: SharedDefines.h:844
@ SPELL_EFFECT_CREATE_ITEM_2
Definition: SharedDefines.h:935
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
Definition: SharedDefines.h:795
@ SPELL_EFFECT_ENERGIZE
Definition: SharedDefines.h:808
@ SPELL_EFFECT_CREATE_RANDOM_ITEM
Definition: SharedDefines.h:837
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
Definition: SharedDefines.h:934
@ SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
Definition: SharedDefines.h:832
@ SPELL_EFFECT_CREATE_ITEM
Definition: SharedDefines.h:802
@ SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON
Definition: SharedDefines.h:503
@ SPELLFAMILY_MAGE
Definition: SharedDefines.h:3531
TotemCategory
Definition: SharedDefines.h:3083
@ SPELL_FAILED_CANT_BE_MILLED
Definition: SharedDefines.h:965
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND
Definition: SharedDefines.h:980
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS
Definition: SharedDefines.h:978
@ SPELL_FAILED_ITEM_AT_MAX_CHARGES
Definition: SharedDefines.h:1128
@ SPELL_FAILED_TARGET_NOT_PLAYER
Definition: SharedDefines.h:1071
@ SPELL_FAILED_ALREADY_AT_FULL_POWER
Definition: SharedDefines.h:953
@ SPELL_FAILED_NOT_TRADEABLE
Definition: SharedDefines.h:1019
@ SPELL_FAILED_ITEM_NOT_READY
Definition: SharedDefines.h:994
@ SPELL_FAILED_NO_CHARGES_REMAIN
Definition: SharedDefines.h:1025
@ SPELL_FAILED_ITEM_GONE
Definition: SharedDefines.h:992
@ SPELL_FAILED_NO_AMMO
Definition: SharedDefines.h:1024
@ SPELL_FAILED_ITEM_NOT_FOUND
Definition: SharedDefines.h:993
@ SPELL_FAILED_EQUIPPED_ITEM
Definition: SharedDefines.h:977
@ SPELL_FAILED_ALREADY_AT_FULL_HEALTH
Definition: SharedDefines.h:951
@ SPELL_FAILED_ON_USE_ENCHANT
Definition: SharedDefines.h:1119
@ SPELL_FAILED_TOTEMS
Definition: SharedDefines.h:1080
@ SPELL_FAILED_ERROR
Definition: SharedDefines.h:981
@ SPELL_FAILED_REAGENTS
Definition: SharedDefines.h:1049
@ SPELL_FAILED_MAX_SOCKETS
Definition: SharedDefines.h:1133
@ SPELL_FAILED_CANT_BE_DISENCHANTED
Definition: SharedDefines.h:963
@ SPELL_FAILED_TOO_MANY_OF_ITEM
Definition: SharedDefines.h:1078
@ SPELL_FAILED_NEED_MORE_ITEMS
Definition: SharedDefines.h:1004
@ SPELL_FAILED_CANT_BE_PROSPECTED
Definition: SharedDefines.h:966
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND
Definition: SharedDefines.h:979
@ SPELL_FAILED_TOTEM_CATEGORY
Definition: SharedDefines.h:1079
@ SKILL_INSCRIPTION
Definition: SharedDefines.h:3002
@ SKILL_ENCHANTING
Definition: SharedDefines.h:2954
@ SKILL_JEWELCRAFTING
Definition: SharedDefines.h:2985
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition: Item.h:301
int32 GetSpellCharges(uint8 index=0) const
Definition: Item.h:314
bool IsBroken() const
Definition: Item.h:257
bool IsWeaponVellum() const
Definition: Item.h:335
bool IsArmorVellum() const
Definition: Item.h:336
Player * GetOwner() const
Definition: Item.cpp:550
ObjectGuid GetOwnerGUID() const
Definition: Item.h:231
uint32 GetCount() const
Definition: Item.h:269
bool IsFitToSpellRequirements(SpellInfo const *spellInfo) const
Definition: Item.cpp:885
int32 SpellCharges
Definition: ItemTemplate.h:601
uint32 SpellTrigger
Definition: ItemTemplate.h:600
int32 SpellId
Definition: ItemTemplate.h:599
uint32 Color
Definition: ItemTemplate.h:610
Definition: ItemTemplate.h:627
uint32 DisenchantID
Definition: ItemTemplate.h:698
uint32 Quality
Definition: ItemTemplate.h:634
uint32 RequiredSkillRank
Definition: ItemTemplate.h:646
uint32 GetMaxStackSize() const
Definition: ItemTemplate.h:737
_Spell Spells[MAX_ITEM_PROTO_SPELLS]
Definition: ItemTemplate.h:670
uint32 RequiredDisenchantSkill
Definition: ItemTemplate.h:692
uint32 Flags
Definition: ItemTemplate.h:635
uint32 RequiredLevel
Definition: ItemTemplate.h:644
uint32 Class
Definition: ItemTemplate.h:629
uint32 ItemLimitCategory
Definition: ItemTemplate.h:695
uint32 SubClass
Definition: ItemTemplate.h:630
_Socket Socket[MAX_ITEM_PROTO_SOCKETS]
Definition: ItemTemplate.h:689
uint32 GetUInt32Value(uint16 index) const
Definition: Object.cpp:305
bool HasItemFitToSpellRequirements(SpellInfo const *spellInfo, Item const *ignoreItem=nullptr) const
Definition: Player.cpp:12462
uint32 GetFreeInventorySpace() const
Definition: PlayerStorage.cpp:489
Item * GetItemByEntry(uint32 entry) const
Definition: PlayerStorage.cpp:3384
bool HasItemCount(uint32 item, uint32 count=1, bool inBankAlso=false) const
Definition: PlayerStorage.cpp:678
bool HasItemTotemCategory(uint32 TotemCategory) const
Definition: PlayerStorage.cpp:874
bool CanNoReagentCast(SpellInfo const *spellInfo) const
Definition: Player.cpp:12507
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition: PlayerStorage.cpp:4036
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition: Player.h:1271
bool CanUseAttackType(uint8 attacktype) const
Definition: Unit.h:951
bool IsFullHealth() const
Definition: Unit.h:784
uint32 GetMaxPower(Powers power) const
Definition: Unit.h:804
void SetUInt32Value(uint16 index, uint32 value)
Definition: Unit.cpp:21180
uint32 GetPower(Powers power) const
Definition: Unit.h:803
bool HaveLootFor(uint32 loot_id) const
Definition: LootMgr.h:224
uint32 GetItemTargetEntry() const
Definition: Spell.h:140
ObjectGuid m_castItemGUID
Definition: Spell.h:523
uint32 BaseLevel
Definition: SpellInfo.h:359
uint32 MaxLevel
Definition: SpellInfo.h:358
std::array< int32, MAX_SPELL_REAGENTS > Reagent
Definition: SpellInfo.h:373
flag96 SpellFamilyFlags
Definition: SpellInfo.h:388
std::array< uint32, 2 > TotemCategory
Definition: SpellInfo.h:378
int32 EquippedItemClass
Definition: SpellInfo.h:375
std::array< uint32, 2 > Totem
Definition: SpellInfo.h:372
std::array< uint32, MAX_SPELL_REAGENTS > ReagentCount
Definition: SpellInfo.h:374
Definition: DBCStructure.h:1841
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition: DBCStructure.h:1844
uint32 slot
Definition: DBCStructure.h:1851

References BASE_ATTACK, SpellInfo::BaseLevel, Player::CanNoReagentCast(), Player::CanStoreNewItem(), Unit::CanUseAttackType(), Unit::CastSpell(), ItemTemplate::Class, _Socket::Color, ItemTemplate::DisenchantID, SpellInfo::DmgClass, EFFECT_1, SpellInfo::Effects, ENCHANTMENT_CAN_SOULBOUND, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_OK, SpellInfo::EquippedItemClass, ItemTemplate::Flags, Item::GetCount(), Item::GetEnchantmentId(), Object::GetEntry(), Player::GetFreeInventorySpace(), Object::GetGUID(), Player::GetItemByEntry(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetEntry(), SpellCastTargets::GetItemTargetGUID(), Unit::GetMaxPower(), ItemTemplate::GetMaxStackSize(), Item::GetOwner(), Item::GetOwnerGUID(), Unit::GetPower(), Player::GetSkillValue(), Item::GetSpellCharges(), Item::GetTemplate(), Object::GetTypeId(), Object::GetUInt32Value(), SpellCastTargets::GetUnitTarget(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), Player::HasItemCount(), Player::HasItemFitToSpellRequirements(), Player::HasItemTotemCategory(), HasTriggeredCastFlag(), LootStore::HaveLootFor(), Item::IsArmorVellum(), Item::IsBroken(), Item::IsFitToSpellRequirements(), Unit::IsFullHealth(), IsTriggered(), Item::IsWeaponVellum(), ITEM_CLASS_ARMOR, ITEM_CLASS_CONSUMABLE, ITEM_CLASS_PROJECTILE, ITEM_CLASS_WEAPON, ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET, ITEM_ENCHANTMENT_TYPE_USE_SPELL, ITEM_FLAG_IS_MILLABLE, ITEM_FLAG_IS_PROSPECTABLE, ITEM_FLAG_NO_REAGENT_COST, ITEM_SPELLTRIGGER_ON_NO_DELAY_USE, ITEM_SPELLTRIGGER_ON_USE, ITEM_SUBCLASS_ARROW, ITEM_SUBCLASS_BULLET, ITEM_SUBCLASS_WEAPON_BOW, ITEM_SUBCLASS_WEAPON_CROSSBOW, ITEM_SUBCLASS_WEAPON_GUN, ITEM_SUBCLASS_WEAPON_THROWN, ITEM_SUBCLASS_WEAPON_WAND, ItemTemplate::ItemLevel, ItemTemplate::ItemLimitCategory, LootTemplates_Milling, LootTemplates_Prospecting, m_attackType, m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, m_weaponItem, MAX_ITEM_PROTO_SOCKETS, MAX_ITEM_PROTO_SPELLS, MAX_ITEM_SPELLS, MAX_POWERS, MAX_SPELL_EFFECTS, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::MaxLevel, NULL_BAG, NULL_SLOT, OFF_ATTACK, PLAYER_AMMO_ID, PRISMATIC_ENCHANTMENT_SLOT, ItemTemplate::Quality, RANGED_ATTACK, SpellInfo::Reagent, SpellInfo::ReagentCount, ItemTemplate::RequiredDisenchantSkill, ItemTemplate::RequiredLevel, ItemTemplate::RequiredSkillRank, Player::SendEquipError(), Unit::SetUInt32Value(), SKILL_ENCHANTING, SKILL_INSCRIPTION, SKILL_JEWELCRAFTING, SpellItemEnchantmentEntry::slot, sObjectMgr, ItemTemplate::Socket, SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_CREATE_ITEM, SPELL_EFFECT_CREATE_ITEM_2, SPELL_EFFECT_CREATE_MANA_GEM, SPELL_EFFECT_CREATE_RANDOM_ITEM, SPELL_EFFECT_DISENCHANT, SPELL_EFFECT_ENCHANT_HELD_ITEM, SPELL_EFFECT_ENCHANT_ITEM, SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY, SPELL_EFFECT_ENERGIZE, SPELL_EFFECT_HEAL, SPELL_EFFECT_MILLING, SPELL_EFFECT_PROSPECTING, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_FAILED_ALREADY_AT_FULL_HEALTH, SPELL_FAILED_ALREADY_AT_FULL_POWER, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_BE_DISENCHANTED, SPELL_FAILED_CANT_BE_MILLED, SPELL_FAILED_CANT_BE_PROSPECTED, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_EQUIPPED_ITEM, SPELL_FAILED_EQUIPPED_ITEM_CLASS, SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND, SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND, SPELL_FAILED_ERROR, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_ITEM_AT_MAX_CHARGES, SPELL_FAILED_ITEM_GONE, SPELL_FAILED_ITEM_NOT_FOUND, SPELL_FAILED_ITEM_NOT_READY, SPELL_FAILED_LOW_CASTLEVEL, SPELL_FAILED_LOWLEVEL, SPELL_FAILED_MAX_SOCKETS, SPELL_FAILED_NEED_MORE_ITEMS, SPELL_FAILED_NO_AMMO, SPELL_FAILED_NO_CHARGES_REMAIN, SPELL_FAILED_NOT_TRADEABLE, SPELL_FAILED_ON_USE_ENCHANT, SPELL_FAILED_REAGENTS, SPELL_FAILED_TARGET_NOT_PLAYER, SPELL_FAILED_TOO_MANY_OF_ITEM, SPELL_FAILED_TOTEM_CATEGORY, SPELL_FAILED_TOTEMS, _Spell::SpellCharges, SPELLFAMILY_MAGE, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, _Spell::SpellId, ItemTemplate::Spells, _Spell::SpellTrigger, sSpellItemEnchantmentStore, ItemTemplate::SubClass, TARGET_UNIT_PET, Object::ToPlayer(), SpellInfo::Totem, SpellInfo::TotemCategory, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, SpellItemEnchantmentEntry::type, and TYPEID_PLAYER.

Referenced by CheckCast().

◆ CheckPetCast()

SpellCastResult Spell::CheckPetCast ( Unit target)
6801{
6802 if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !HasTriggeredCastFlag(TRIGGERED_IGNORE_CAST_IN_PROGRESS)) //prevent spellcast interruption by another spellcast
6804
6805 // dead owner (pets still alive when owners ressed?)
6806 if (Unit* owner = m_caster->GetCharmerOrOwner())
6807 if (!owner->IsAlive() && m_caster->GetEntry() != 30230) // Rise Ally
6809
6810 if (!target && m_targets.GetUnitTarget())
6811 target = m_targets.GetUnitTarget();
6812
6814 {
6815 if (!target)
6817 m_targets.SetUnitTarget(target);
6818 }
6819
6820 // xinef: Calculate power cost here, so funciton checking power can work properly and dont return bad results
6822
6823 // cooldown
6824 if (Creature const* creatureCaster = m_caster->ToCreature())
6825 if (creatureCaster->HasSpellCooldown(m_spellInfo->Id))
6827
6828 // Check if spell is affected by GCD
6832
6833 return CheckCast(true);
6834}
bool HasGlobalCooldown(SpellInfo const *spellInfo) const
Definition: CharmInfo.cpp:397
void SetUnitTarget(Unit *target)
Definition: Spell.cpp:239
int32 CalcPowerCost(Unit const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2400
uint32 StartRecoveryCategory
Definition: SpellInfo.h:350

References SpellInfo::CalcPowerCost(), CheckCast(), Unit::GetCharmerOrOwner(), Unit::GetCharmInfo(), Object::GetEntry(), CharmInfo::GetGlobalCooldownMgr(), SpellCastTargets::GetUnitTarget(), GlobalCooldownMgr::HasGlobalCooldown(), HasTriggeredCastFlag(), Unit::HasUnitState(), SpellInfo::Id, m_caster, m_powerCost, m_spellInfo, m_spellSchoolMask, m_targets, SpellInfo::NeedsExplicitUnitTarget(), SpellCastTargets::SetUnitTarget(), SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_CASTER_DEAD, SPELL_FAILED_NOT_READY, SPELL_FAILED_SPELL_IN_PROGRESS, SpellInfo::StartRecoveryCategory, Object::ToCreature(), TRIGGERED_IGNORE_CAST_IN_PROGRESS, and UNIT_STATE_CASTING.

Referenced by CanAutoCast(), WorldSession::HandlePetActionHelper(), and WorldSession::HandlePetCastSpellOpcode().

◆ CheckPower()

SpellCastResult Spell::CheckPower ( )
7120{
7121 // item cast not used power
7122 if (m_CastItem)
7123 return SPELL_CAST_OK;
7124
7125 //While .cheat power is enabled dont check if we need power to cast the spell
7127 {
7129 {
7130 return SPELL_CAST_OK;
7131 }
7132 }
7133
7134 // health as power used - need check health amount
7136 {
7139 return SPELL_CAST_OK;
7140 }
7141 // Check valid power type
7143 {
7144 LOG_ERROR("spells", "Spell::CheckPower: Unknown power type '{}'", m_spellInfo->PowerType);
7145 return SPELL_FAILED_UNKNOWN;
7146 }
7147
7148 //check rune cost only if a spell has PowerType == POWER_RUNE
7150 {
7152 if (failReason != SPELL_CAST_OK)
7153 return failReason;
7154 }
7155
7156 // Check power amount
7159 return SPELL_FAILED_NO_POWER;
7160 else
7161 return SPELL_CAST_OK;
7162}
@ CHEAT_POWER
Definition: Player.h:1001
PowerType
Definition: VehicleDefines.h:29
@ POWER_HEALTH
Definition: SharedDefines.h:278
@ POWER_RUNE
Definition: SharedDefines.h:274
@ SPELL_FAILED_NO_POWER
Definition: SharedDefines.h:1034
@ SPELL_FAILED_UNKNOWN
Definition: SharedDefines.h:1136
uint32 GetHealth() const
Definition: Unit.h:781
SpellCastResult CheckRuneCost(uint32 RuneCostID)
Definition: Spell.cpp:5394
uint32 RuneCostID
Definition: SpellInfo.h:368
uint32 PowerType
Definition: SpellInfo.h:362

References CHEAT_POWER, CheckRuneCost(), Player::GetCommandStatus(), Unit::GetHealth(), Unit::GetPower(), Object::GetTypeId(), LOG_ERROR, m_caster, m_CastItem, m_powerCost, m_spellInfo, MAX_POWERS, POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, SPELL_CAST_OK, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_NO_POWER, SPELL_FAILED_UNKNOWN, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by CheckCast().

◆ CheckRange()

SpellCastResult Spell::CheckRange ( bool  strict)
7034{
7035 // Don't check for instant cast spells
7036 if (!strict && m_casttime == 0)
7037 return SPELL_CAST_OK;
7038
7039 uint32 range_type = 0;
7040
7042 {
7043 // check needed by 68766 51693 - both spells are cast on enemies and have 0 max range
7044 // these are triggered by other spells - possibly we should omit range check in that case?
7045 if (m_spellInfo->RangeEntry->ID == 1)
7046 return SPELL_CAST_OK;
7047
7048 range_type = m_spellInfo->RangeEntry->Flags;
7049 }
7050
7051 Unit* target = m_targets.GetUnitTarget();
7052 float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo);
7053 float min_range = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo);
7054
7055 // xinef: hack for npc shooters
7056 if (min_range && GetCaster()->GetTypeId() == TYPEID_UNIT && !GetCaster()->GetOwnerGUID().IsPlayer() && min_range <= 6.0f)
7057 range_type = SPELL_RANGE_RANGED;
7058
7059 if (Player* modOwner = m_caster->GetSpellModOwner())
7060 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
7061
7062 // xinef: dont check max_range to strictly after cast
7063 if (range_type != SPELL_RANGE_MELEE && !strict)
7064 max_range += std::min(3.0f, max_range * 0.1f); // 10% but no more than 3yd
7065
7066 if (target)
7067 {
7068 if (target != m_caster)
7069 {
7070 // Xinef: Spells with 5yd range can hit target 9yd away?
7071 if (range_type == SPELL_RANGE_MELEE)
7072 {
7073 float real_max_range = max_range;
7074 if (m_caster->GetTypeId() != TYPEID_UNIT && m_caster->isMoving() && target->isMoving() && !m_caster->IsWalking() && !target->IsWalking())
7075 real_max_range -= MIN_MELEE_REACH; // Because of lag, we can not check too strictly here (is only used if both caster and target are moving)
7076 else
7077 real_max_range -= 2 * MIN_MELEE_REACH;
7078
7079 if (!m_caster->IsWithinMeleeRange(target, std::max(real_max_range, 0.0f)))
7081 }
7082 else if (!m_caster->IsWithinCombatRange(target, max_range))
7083 return SPELL_FAILED_OUT_OF_RANGE; //0x5A;
7084
7086 {
7087 if (m_caster->IsWithinMeleeRange(target))
7089 }
7090
7091 if (m_caster->GetTypeId() == TYPEID_PLAYER && (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(static_cast<float>(M_PI), target))
7093 }
7094
7095 // Xinef: check min range for self casts
7096 if (min_range && range_type != SPELL_RANGE_RANGED && m_caster->IsWithinCombatRange(target, min_range)) // skip this check if min_range = 0
7098 }
7099
7100 if (GameObject* goTarget = m_targets.GetGOTarget())
7101 {
7102 if (!goTarget->IsAtInteractDistance(m_caster->ToPlayer(), m_spellInfo))
7103 {
7105 }
7106 }
7107
7108 if (m_targets.HasDst() && !m_targets.HasTraj())
7109 {
7110 if (!m_caster->IsWithinDist3d(m_targets.GetDstPos(), max_range))
7112 if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
7114 }
7115
7116 return SPELL_CAST_OK;
7117}
#define MIN_MELEE_REACH
Definition: ObjectDefines.h:47
@ SPELL_RANGE_MELEE
Definition: Spell.h:89
@ SPELL_RANGE_RANGED
Definition: Spell.h:90
@ SPELLMOD_RANGE
Definition: SpellDefines.h:82
@ SPELL_FACING_FLAG_INFRONT
Definition: SpellDefines.h:126
@ SPELL_FAILED_TOO_CLOSE
Definition: SharedDefines.h:1077
@ SPELL_FAILED_OUT_OF_RANGE
Definition: SharedDefines.h:1046
bool IsWithinDist3d(float x, float y, float z, float dist) const
Definition: Object.cpp:1295
bool HasInArc(float arcangle, const Position *pos, float targetRadius=0.0f) const
Definition: Position.cpp:140
bool IsWithinCombatRange(Unit const *obj, float dist2compare) const
Definition: Unit.cpp:649
float GetSpellMinRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition: Unit.cpp:15081
bool IsWithinMeleeRange(Unit const *obj, float dist=0.f) const
Definition: Unit.cpp:665
float GetSpellMaxRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition: Unit.cpp:15061
bool IsWalking() const
Definition: Unit.h:1721
Unit * GetCaster() const
Definition: Spell.h:573
SpellRangeEntry const * RangeEntry
Definition: SpellInfo.h:369
uint32 FacingCasterFlags
Definition: SpellInfo.h:338
uint32 Flags
Definition: DBCStructure.h:1797
uint32 ID
Definition: DBCStructure.h:1794

References SpellInfo::DmgClass, SpellInfo::FacingCasterFlags, SpellRangeEntry::Flags, GetCaster(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetGOTarget(), Unit::GetSpellMaxRangeForTarget(), Unit::GetSpellMinRangeForTarget(), Unit::GetSpellModOwner(), Object::GetTypeId(), SpellCastTargets::GetUnitTarget(), SpellCastTargets::HasDst(), Position::HasInArc(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellRangeEntry::ID, Unit::isMoving(), Unit::IsWalking(), Unit::IsWithinCombatRange(), WorldObject::IsWithinDist3d(), Unit::IsWithinMeleeRange(), m_caster, m_casttime, m_spellInfo, m_targets, MIN_MELEE_REACH, SpellInfo::RangeEntry, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_RANGED, SPELL_FACING_FLAG_INFRONT, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_TOO_CLOSE, SPELL_FAILED_UNIT_NOT_INFRONT, SPELL_RANGE_MELEE, SPELL_RANGE_RANGED, SPELLMOD_RANGE, Object::ToPlayer(), TYPEID_PLAYER, and TYPEID_UNIT.

Referenced by CheckCast().

◆ CheckRuneCost()

SpellCastResult Spell::CheckRuneCost ( uint32  RuneCostID)
5395{
5396 if (m_spellInfo->PowerType != POWER_RUNE || !RuneCostID)
5397 return SPELL_CAST_OK;
5398
5400 return SPELL_CAST_OK;
5401
5402 Player* player = m_caster->ToPlayer();
5403 //If we are in .cheat power mode we dont need to check the cost as we are expected to be able to use it anyways (infinite power)
5404 if (player->GetCommandStatus(CHEAT_POWER))
5405 {
5406 return SPELL_CAST_OK;
5407 }
5408
5410 return SPELL_CAST_OK;
5411
5412 SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(RuneCostID);
5413
5414 if (!src)
5415 return SPELL_CAST_OK;
5416
5417 if (src->NoRuneCost())
5418 return SPELL_CAST_OK;
5419
5420 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5421
5422 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5423 {
5424 runeCost[i] = src->RuneCost[i];
5425 if (Player* modOwner = m_caster->GetSpellModOwner())
5426 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5427 }
5428
5429 runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
5430
5431 for (uint32 i = 0; i < MAX_RUNES; ++i)
5432 {
5433 RuneType rune = player->GetCurrentRune(i);
5434 if ((player->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
5435 runeCost[rune]--;
5436 }
5437
5438 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5439 if (runeCost[i] > 0)
5440 runeCost[RUNE_DEATH] += runeCost[i];
5441
5442 if (runeCost[RUNE_DEATH] > MAX_RUNES)
5443 return SPELL_FAILED_NO_POWER; // not sure if result code is correct
5444
5445 return SPELL_CAST_OK;
5446}
DBCStorage< SpellRuneCostEntry > sSpellRuneCostStore(SpellRuneCostfmt)
RuneType
Definition: Player.h:408
@ RUNE_DEATH
Definition: Player.h:412
@ NUM_RUNE_TYPES
Definition: Player.h:413
#define MAX_RUNES
Definition: Player.h:398
@ CLASS_CONTEXT_ABILITY
Definition: UnitDefines.h:213
@ SPELLMOD_COST
Definition: SpellDefines.h:91
@ CLASS_DEATH_KNIGHT
Definition: SharedDefines.h:146
uint32 GetRuneCooldown(uint8 index) const
Definition: Player.h:2484
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition: Player.cpp:1279
RuneType GetCurrentRune(uint8 index) const
Definition: Player.h:2483
Definition: DBCStructure.h:1805
uint32 RuneCost[3]
Definition: DBCStructure.h:1807
bool NoRuneCost() const
Definition: DBCStructure.h:1810

References CHEAT_POWER, CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, Player::GetCommandStatus(), Player::GetCurrentRune(), Player::GetRuneCooldown(), Unit::GetSpellModOwner(), Object::GetTypeId(), SpellInfo::Id, Player::IsClass(), m_caster, m_spellInfo, MAX_RUNES, SpellRuneCostEntry::NoRuneCost(), NUM_RUNE_TYPES, POWER_RUNE, SpellInfo::PowerType, RUNE_DEATH, SpellRuneCostEntry::RuneCost, SPELL_CAST_OK, SPELL_FAILED_NO_POWER, SPELLMOD_COST, sSpellRuneCostStore, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by CheckPower().

◆ CheckScriptEffectImplicitTargets()

bool Spell::CheckScriptEffectImplicitTargets ( uint32  effIndex,
uint32  effIndexToCheck 
)
protected
8698{
8699 // Skip if there are not any script
8700 if (!m_loadedScripts.size())
8701 return true;
8702
8703 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr)
8704 {
8705 std::list<SpellScript::ObjectTargetSelectHandler>::iterator targetSelectHookEnd = (*itr)->OnObjectTargetSelect.end(), targetSelectHookItr = (*itr)->OnObjectTargetSelect.begin();
8706 for (; targetSelectHookItr != targetSelectHookEnd; ++targetSelectHookItr)
8707 if (((*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8708 (!(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8709 return false;
8710
8711 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator areaTargetSelectHookEnd = (*itr)->OnObjectAreaTargetSelect.end(), areaTargetSelectHookItr = (*itr)->OnObjectAreaTargetSelect.begin();
8712 for (; areaTargetSelectHookItr != areaTargetSelectHookEnd; ++areaTargetSelectHookItr)
8713 if (((*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8714 (!(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8715 return false;
8716 }
8717 return true;
8718}

References m_loadedScripts, and m_spellInfo.

Referenced by SelectEffectImplicitTargets().

◆ CheckSpellFocus()

SpellCastResult Spell::CheckSpellFocus ( )
7733{
7734 // check spell focus object
7736 {
7738 Cell cell(p);
7739
7740 GameObject* ok = nullptr;
7743
7745 Map& map = *m_caster->GetMap();
7746 cell.Visit(p, object_checker, map, *m_caster, m_caster->GetVisibilityRange());
7747
7748 if (!ok)
7750
7751 focusObject = ok; // game object found in range
7752 }
7753 return SPELL_CAST_OK;
7754}
@ SPELL_FAILED_REQUIRES_SPELL_FOCUS
Definition: SharedDefines.h:1051
CellCoord ComputeCellCoord(float x, float y)
Definition: GridDefines.h:191
Definition: TypeContainer.h:101
Definition: TypeContainerVisitor.h:84
Definition: Cell.h:46
Definition: GridNotifiers.h:319
Definition: GridNotifiers.h:657
Definition: Map.h:313
void Visit(const Cell &cell, TypeContainerVisitor< T, CONTAINER > &visitor)
Definition: Map.h:873
uint32 RequiresSpellFocus
Definition: SpellInfo.h:337

References Acore::ComputeCellCoord(), focusObject, WorldObject::GetMap(), Position::GetPositionX(), Position::GetPositionY(), WorldObject::GetVisibilityRange(), m_caster, m_spellInfo, SpellInfo::RequiresSpellFocus, SPELL_CAST_OK, SPELL_FAILED_REQUIRES_SPELL_FOCUS, and Cell::Visit().

Referenced by CheckCast().

◆ CheckSrc()

void Spell::CheckSrc ( )
inline
bool HasSrc() const
Definition: Spell.h:164
void SetSrc(float x, float y, float z)
Definition: Spell.cpp:367

References SpellCastTargets::HasSrc(), m_caster, m_targets, and SpellCastTargets::SetSrc().

◆ CleanupTargetList()

void Spell::CleanupTargetList ( )
2372{
2373 m_UniqueTargetInfo.clear();
2374 m_UniqueGOTargetInfo.clear();
2375 m_UniqueItemInfo.clear();
2376 m_delayMoment = 0;
2378}
uint64 m_delayTrajectory
Definition: Spell.h:640

References m_delayMoment, m_delayTrajectory, m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

Referenced by spell_dk_raise_dead::CheckCast(), and Spell().

◆ Delayed()

void Spell::Delayed ( )
7757{
7758 if (!m_caster)// || m_caster->GetTypeId() != TYPEID_PLAYER)
7759 return;
7760
7761 //if (m_spellState == SPELL_STATE_DELAYED)
7762 // return; // spell is active and can't be time-backed
7763
7764 if (isDelayableNoMore()) // Spells may only be delayed twice
7765 return;
7766
7768 return;
7769
7770 // spells not loosing casting time (slam, dynamites, bombs..)
7771 //if (!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
7772 // return;
7773
7774 //check pushback reduce
7775 int32 delaytime = 500; // spellcasting delay is normally 500ms
7776 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7779 if (delayReduce >= 100)
7780 return;
7781
7782 AddPct(delaytime, -delayReduce);
7783
7784 if (m_timer + delaytime > m_casttime)
7785 {
7786 delaytime = m_casttime - m_timer;
7788 }
7789 else
7790 m_timer += delaytime;
7791
7792 LOG_DEBUG("spells", "Spell {} partially interrupted for ({}) ms at damage", m_spellInfo->Id, delaytime);
7793
7794 WorldPacket data(SMSG_SPELL_DELAYED, 8 + 4);
7795 data << m_caster->GetPackGUID();
7796 data << uint32(delaytime);
7797
7798 m_caster->SendMessageToSet(&data, true);
7799}
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:168
T AddPct(T &base, U pct)
Definition: Util.h:67
@ SPELL_AURA_REDUCE_PUSHBACK
Definition: SpellAuraDefines.h:212
@ SPELLMOD_NOT_LOSE_CASTING_TIME
Definition: SpellDefines.h:86
@ SPELL_ATTR6_NO_PUSHBACK
Definition: SharedDefines.h:619
@ SMSG_SPELL_DELAYED
Definition: Opcodes.h:512
PackedGuid const & GetPackGUID() const
Definition: Object.h:111
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition: Object.cpp:2080
void ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell *spell=nullptr, bool temporaryPet=false)
Definition: Player.cpp:9685
int32 GetTotalAuraModifier(AuraType auratype) const
Definition: Unit.cpp:5855
Definition: WorldPacket.h:27
bool isDelayableNoMore()
Definition: Spell.h:628

References AddPct(), Player::ApplySpellMod(), Object::GetPackGUID(), Unit::GetTotalAuraModifier(), SpellInfo::HasAttribute(), SpellInfo::Id, isDelayableNoMore(), LOG_DEBUG, m_caster, m_casttime, m_spellInfo, m_timer, WorldObject::SendMessageToSet(), SMSG_SPELL_DELAYED, SPELL_ATTR6_NO_PUSHBACK, SPELL_AURA_REDUCE_PUSHBACK, SPELLMOD_NOT_LOSE_CASTING_TIME, and Object::ToPlayer().

◆ DelayedChannel()

void Spell::DelayedChannel ( )
7802{
7804 return;
7805
7806 if (isDelayableNoMore()) // Spells may only be delayed twice
7807 return;
7808
7810 return;
7811
7812 //check pushback reduce
7813 // should be affected by modifiers, not take the dbc duration.
7815
7816 int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit
7817 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7820 if (delayReduce >= 100)
7821 return;
7822
7823 AddPct(delaytime, -delayReduce);
7824
7825 if (m_timer <= delaytime)
7826 {
7827 delaytime = m_timer;
7828 m_timer = 0;
7829 }
7830 else
7831 m_timer -= delaytime;
7832
7833 LOG_DEBUG("spells.aura", "Spell {} partially interrupted for {} ms, new duration: {} ms", m_spellInfo->Id, delaytime, m_timer);
7834
7835 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7836 if ((*ihit).missCondition == SPELL_MISS_NONE)
7837 if (Unit* unit = (m_caster->GetGUID() == ihit->targetGUID) ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
7838 unit->DelayOwnedAuras(m_spellInfo->Id, m_originalCasterGUID, delaytime);
7839
7840 // partially interrupt persistent area auras
7842 dynObj->Delay(delaytime);
7843
7845}
T CalculatePct(T base, U pct)
Definition: Util.h:61
Definition: DynamicObject.h:35
DynamicObject * GetDynObject(uint32 spellId)
Definition: Unit.cpp:6073
uint32 getState() const
Definition: Spell.h:482
int32 GetDuration() const
Definition: SpellInfo.cpp:2337

References AddPct(), Player::ApplySpellMod(), CalculatePct(), SpellInfo::GetDuration(), Unit::GetDynObject(), Object::GetGUID(), getState(), Unit::GetTotalAuraModifier(), Object::GetTypeId(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, isDelayableNoMore(), LOG_DEBUG, m_caster, m_channeledDuration, m_originalCasterGUID, m_spellInfo, m_timer, m_UniqueTargetInfo, SendChannelUpdate(), SPELL_ATTR6_NO_PUSHBACK, SPELL_AURA_REDUCE_PUSHBACK, SPELL_MISS_NONE, SPELL_STATE_CASTING, SPELLMOD_NOT_LOSE_CASTING_TIME, Object::ToPlayer(), and TYPEID_PLAYER.

◆ DoAllEffectOnLaunchTarget()

void Spell::DoAllEffectOnLaunchTarget ( TargetInfo targetInfo,
float *  multiplier 
)
protected
8285{
8286 Unit* unit = nullptr;
8287 // In case spell hit target, do all effect on that target
8288 if (targetInfo.missCondition == SPELL_MISS_NONE)
8289 unit = m_caster->GetGUID() == targetInfo.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, targetInfo.targetGUID);
8290 // In case spell reflect from target, do all effect on caster (if hit)
8291 else if (targetInfo.missCondition == SPELL_MISS_REFLECT && targetInfo.reflectResult == SPELL_MISS_NONE)
8292 unit = m_caster;
8293 if (!unit)
8294 return;
8295
8296 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8297 {
8298 if (targetInfo.effectMask & (1 << i))
8299 {
8300 m_damage = 0;
8301 m_healing = 0;
8302
8303 HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
8304
8305 if (m_damage > 0)
8306 {
8307 // Xinef: Area Auras, AoE Targetting spells AND Chain Target spells (cleave etc.)
8308 if (m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsTargetingArea() || (m_spellInfo->Effects[i].ChainTarget > 1 && m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MAGIC))
8309 {
8312 {
8313 uint32 targetAmount = m_UniqueTargetInfo.size();
8314 if (targetAmount > 10)
8315 m_damage = m_damage * 10 / targetAmount;
8316 }
8317 }
8318 }
8319
8320 if (m_applyMultiplierMask & (1 << i))
8321 {
8323 m_damageMultipliers[i] *= multiplier[i];
8324 }
8325 targetInfo.damage += m_damage;
8326 }
8327 }
8328
8329 // xinef: totem's inherit owner crit chance and dancing rune weapon
8330 Unit* caster = m_caster;
8331 if (m_caster->IsTotem() || m_caster->GetEntry() == 27893)
8332 {
8333 if (Unit* owner = m_caster->GetOwner())
8334 caster = owner;
8335 }
8336 else if (m_originalCaster)
8337 caster = m_originalCaster;
8338
8339 float critChance = caster->SpellDoneCritChance(unit, m_spellInfo, m_spellSchoolMask, m_attackType, false);
8340 critChance = unit->SpellTakenCritChance(caster, m_spellInfo, m_spellSchoolMask, critChance, m_attackType, false);
8341 targetInfo.crit = roll_chance_f(std::max(0.0f, critChance));
8342}
bool roll_chance_f(float chance)
Definition: Random.h:53
float SpellTakenCritChance(Unit const *caster, SpellInfo const *spellProto, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType, bool skipEffectCheck) const
Definition: Unit.cpp:11991
float SpellDoneCritChance(Unit const *, SpellInfo const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType, bool skipEffectCheck) const
Definition: Unit.cpp:11916
int32 CalculateAOEDamageReduction(int32 damage, uint32 schoolMask, Unit *caster) const
Definition: Unit.cpp:20284
uint32 SchoolMask
Definition: SpellInfo.h:392

References Unit::CalculateAOEDamageReduction(), TargetInfo::crit, TargetInfo::damage, SpellInfo::DmgClass, TargetInfo::effectMask, SpellInfo::Effects, Object::GetEntry(), Object::GetGUID(), Unit::GetOwner(), Object::GetTypeId(), ObjectAccessor::GetUnit(), HandleEffects(), Unit::IsTotem(), m_applyMultiplierMask, m_attackType, m_caster, m_damage, m_damageMultipliers, m_healing, m_originalCaster, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, TargetInfo::reflectResult, roll_chance_f(), SpellInfo::SchoolMask, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_MISS_NONE, SPELL_MISS_REFLECT, Unit::SpellDoneCritChance(), Unit::SpellTakenCritChance(), TargetInfo::targetGUID, and TYPEID_PLAYER.

Referenced by HandleLaunchPhase().

◆ DoAllEffectOnTarget() [1/3]

void Spell::DoAllEffectOnTarget ( GOTargetInfo target)
protected
3333{
3334 if (target->processed) // Check target
3335 return;
3336 target->processed = true; // Target checked in apply effects procedure
3337
3338 uint32 effectMask = target->effectMask;
3339 if (!effectMask)
3340 return;
3341
3342 GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
3343 if (!go)
3344 return;
3345
3348
3349 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3350 if (effectMask & (1 << effectNumber))
3351 HandleEffects(nullptr, nullptr, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3352
3353 // xinef: inform ai about spellhit
3355
3357
3359}
virtual void SpellHit(Unit *, SpellInfo const *)
Definition: GameObjectAI.h:67
GameObjectAI * AI() const
Definition: GameObject.h:307
void CallScriptBeforeHitHandlers(SpellMissInfo missInfo)
Definition: Spell.cpp:8616
void CallScriptOnHitHandlers()
Definition: Spell.cpp:8629
void CallScriptAfterHitHandlers()
Definition: Spell.cpp:8642

References GameObject::AI(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), Spell::GOTargetInfo::effectMask, Map::GetGameObject(), WorldObject::GetMap(), HandleEffects(), m_caster, m_spellInfo, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), Spell::GOTargetInfo::processed, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_MISS_NONE, GameObjectAI::SpellHit(), and Spell::GOTargetInfo::targetGUID.

◆ DoAllEffectOnTarget() [2/3]

void Spell::DoAllEffectOnTarget ( ItemTargetInfo target)
protected
3362{
3363 uint32 effectMask = target->effectMask;
3364 if (!target->item || !effectMask)
3365 return;
3366
3369
3370 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3371 if (effectMask & (1 << effectNumber))
3372 HandleEffects(nullptr, target->item, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3373
3375
3377}

References CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), Spell::ItemTargetInfo::effectMask, HandleEffects(), Spell::ItemTargetInfo::item, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), SPELL_EFFECT_HANDLE_HIT_TARGET, and SPELL_MISS_NONE.

◆ DoAllEffectOnTarget() [3/3]

void Spell::DoAllEffectOnTarget ( TargetInfo target)
protected
Todo:
: check how broad this rule should be
2610{
2611 if (!target || target->processed)
2612 return;
2613
2614 target->processed = true; // Target checked in apply effects procedure
2615
2616 // Get mask of effects for target
2617 uint8 mask = target->effectMask;
2618
2619 Unit* effectUnit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
2620 if (!effectUnit && !target->targetGUID.IsPlayer()) // only players may be targeted across maps
2621 return;
2622
2623 if (!effectUnit || m_spellInfo->Id == 45927)
2624 {
2625 uint8 farMask = 0;
2626 // create far target mask
2627 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2628 if (m_spellInfo->Effects[i].IsFarUnitTargetEffect())
2629 if ((1 << i) & mask)
2630 farMask |= (1 << i);
2631
2632 if (!farMask)
2633 return;
2634 // find unit in world
2635 // Xinef: FindUnit Access without Map check!!! Intended
2636 effectUnit = ObjectAccessor::FindPlayer(target->targetGUID);
2637 if (!effectUnit)
2638 return;
2639
2640 // do far effects on the unit
2641 // can't use default call because of threading, do stuff as fast as possible
2642 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2643 if (farMask & (1 << i))
2644 HandleEffects(effectUnit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_HIT_TARGET);
2645 return;
2646 }
2647
2648 if (effectUnit->IsAlive() != target->alive)
2649 return;
2650
2651 // Xinef: absorb delayed projectiles for 500ms
2653 (GameTime::GetGameTimeMS().count() - target->timeDelay) <= effectUnit->m_lastSanctuaryTime && GameTime::GetGameTimeMS().count() < (effectUnit->m_lastSanctuaryTime + 500) &&
2654 effectUnit->FindMap() && !effectUnit->FindMap()->IsDungeon()
2655 )
2656 return; // No missinfo in that case
2657
2658 // Get original caster (if exist) and calculate damage/healing from him data
2660
2661 // Skip if m_originalCaster not avaiable
2662 if (!caster)
2663 return;
2664
2665 SpellMissInfo missInfo = target->missCondition;
2666
2667 // Need init unitTarget by default unit (can changed in code on reflect)
2668 // Or on missInfo != SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
2669 unitTarget = effectUnit;
2670
2671 // Reset damage/healing counter
2672 m_damage = target->damage;
2673 m_healing = -target->damage;
2674
2675 m_spellAura = nullptr; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
2676
2679
2680 //Spells with this flag cannot trigger if effect is casted on self
2682 bool reflectedSpell = missInfo == SPELL_MISS_REFLECT;
2683 Unit* spellHitTarget = nullptr;
2684
2685 if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
2686 spellHitTarget = unitTarget;
2687 else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
2688 {
2689 missInfo = target->reflectResult;
2690 if (missInfo == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
2691 {
2692 spellHitTarget = m_caster;
2694 if (m_caster->GetTypeId() == TYPEID_UNIT)
2696 }
2697 }
2698
2699 if (spellHitTarget)
2700 {
2701 SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura);
2702 if (missInfo2 != SPELL_MISS_NONE)
2703 {
2704 if (missInfo2 != SPELL_MISS_MISS)
2705 m_caster->SendSpellMiss(spellHitTarget, m_spellInfo->Id, missInfo2);
2706 m_damage = 0;
2707 spellHitTarget = nullptr;
2708
2709 // Xinef: if missInfo2 is MISS_EVADE, override base missinfo data
2710 if (missInfo2 == SPELL_MISS_EVADE)
2711 missInfo = SPELL_MISS_EVADE;
2712 }
2713 }
2714
2715 // Do not take combo points on dodge and miss
2716 if (missInfo != SPELL_MISS_NONE && m_needComboPoints && m_targets.GetUnitTargetGUID() == target->targetGUID)
2717 {
2718 m_needComboPoints = false;
2719 // Restore spell mods for a miss/dodge/parry Cold Blood
2721 if (m_caster->GetTypeId() == TYPEID_PLAYER && (missInfo == SPELL_MISS_MISS || missInfo == SPELL_MISS_DODGE || missInfo == SPELL_MISS_PARRY))
2722 m_caster->ToPlayer()->RestoreSpellMods(this, 14177);
2723 }
2724
2725 // Fill base trigger info
2726 uint32 procAttacker = m_procAttacker;
2727 uint32 procVictim = m_procVictim;
2728 uint32 procEx = m_procEx;
2729
2730 // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now
2731 if (canEffectTrigger && !procAttacker && !procVictim)
2732 {
2733 bool positive = true;
2734 if (m_damage > 0)
2735 positive = false;
2736 else if (!m_healing)
2737 {
2738 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2739 // If at least one effect negative spell is negative hit
2740 // Xinef: if missInfo is immune state check all effects to properly determine positiveness of spell
2741 if ((missInfo == SPELL_MISS_IMMUNE2 || (mask & (1 << i))) && !m_spellInfo->IsPositiveEffect(i))
2742 {
2743 positive = false;
2744 break;
2745 }
2746 }
2747 switch (m_spellInfo->DmgClass)
2748 {
2750 if (positive)
2751 {
2754 }
2755 else
2756 {
2759 }
2760 break;
2762 if (positive)
2763 {
2766 }
2767 else
2768 {
2771 }
2772 break;
2773 }
2774 }
2776
2777 // All calculated do it!
2778 // Do healing and triggers
2779 if (m_healing > 0)
2780 {
2781 bool crit = target->crit;
2782 uint32 addhealth = m_healing;
2783
2784 if (crit)
2785 {
2786 procEx |= PROC_EX_CRITICAL_HIT;
2787 addhealth = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, addhealth, nullptr);
2788 }
2789 else
2790 procEx |= PROC_EX_NORMAL_HIT;
2791
2792 HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask());
2793
2794 // Xinef: override with forced crit, only visual result
2795 if (GetSpellValue()->ForcedCritResult)
2796 {
2797 crit = true;
2798 procEx |= PROC_EX_CRITICAL_HIT;
2799 }
2800
2801 int32 gain = caster->HealBySpell(healInfo, crit);
2802 unitTarget->getHostileRefMgr().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
2803 m_healing = gain;
2804
2805 // Xinef: if heal acutally healed something, add no overheal flag
2806 if (m_healing)
2807 procEx |= PROC_EX_NO_OVERHEAL;
2808
2809 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2810 if (canEffectTrigger)
2811 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2812 m_triggeredByAuraSpell.effectIndex, this, nullptr, &healInfo);
2813 }
2814 // Do damage and triggers
2815 else if (m_damage > 0)
2816 {
2818
2819 // Fill base damage struct (unitTarget - is real spell target)
2821
2822 // Add bonuses and fill damageInfo struct
2823 // Dancing Rune Weapon...
2824 if (m_caster->GetEntry() == 27893)
2825 {
2826 if (Unit* owner = m_caster->GetOwner())
2827 owner->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2828 }
2829 else
2830 caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2831
2832 // xinef: override miss info after absorb / block calculations
2833 if (missInfo == SPELL_MISS_NONE && damageInfo.damage == 0)
2834 {
2835 //if (damageInfo.absorb > 0)
2836 // missInfo = SPELL_MISS_ABSORB;
2837 if (damageInfo.blocked)
2838 missInfo = SPELL_MISS_BLOCK;
2839 }
2840
2841 // Xinef: override with forced crit, only visual result
2842 if (GetSpellValue()->ForcedCritResult)
2843 {
2844 damageInfo.HitInfo |= SPELL_HIT_TYPE_CRIT;
2845 }
2846
2847 Unit::DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
2848
2849 // xinef: health leech handling
2851 {
2852 uint8 effIndex = EFFECT_0;
2853 for (; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2854 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_HEALTH_LEECH)
2855 break;
2856
2857 float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
2858
2859 // get max possible damage, don't count overkill for heal
2860 uint32 healthGain = uint32(-unitTarget->GetHealthGain(-int32(damageInfo.damage)) * healMultiplier);
2861
2862 if (m_caster->IsAlive())
2863 {
2864 healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL, effIndex);
2865 healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
2866
2867 HealInfo healInfo(m_caster, m_caster, healthGain, m_spellInfo, m_spellInfo->GetSchoolMask());
2868 m_caster->HealBySpell(healInfo);
2869 }
2870 }
2871
2872 // Send log damage message to client
2873 caster->SendSpellNonMeleeDamageLog(&damageInfo);
2874 // Xinef: send info to target about reflect
2875 if (reflectedSpell)
2876 effectUnit->SendSpellNonMeleeReflectLog(&damageInfo, effectUnit);
2877
2878 procEx |= createProcExtendMask(&damageInfo, missInfo);
2879 procVictim |= PROC_FLAG_TAKEN_DAMAGE;
2880
2881 caster->DealSpellDamage(&damageInfo, true, this);
2882
2883 // do procs after damage, eg healing effects
2884 // no need to check if target is alive, done in procdamageandspell
2885
2886 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2887 if (canEffectTrigger)
2888 {
2889 DamageInfo dmgInfo(damageInfo, SPELL_DIRECT_DAMAGE);
2890 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2891 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2892
2895 caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx);
2896 }
2897
2898 m_damage = damageInfo.damage;
2899 }
2900 // Passive spell hits/misses or active spells only misses (only triggers)
2901 else
2902 {
2903 // Fill base damage struct (unitTarget - is real spell target)
2905 procEx |= createProcExtendMask(&damageInfo, missInfo);
2906 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2907 if (canEffectTrigger)
2908 {
2909 DamageInfo dmgInfo(damageInfo, NODAMAGE);
2910 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2911 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2912
2913 // Xinef: eg. rogue poisons can proc off cheap shot, etc. so this block should be here also
2914 // Xinef: ofc count only spells that HIT the target, little hack used to fool the system
2918 }
2919
2920 // Failed Pickpocket, reveal rogue
2922 {
2926 }
2927 }
2928
2929 if (m_caster)
2930 {
2932 {
2934
2935 // Patch 3.0.8: All player spells which cause a creature to become aggressive to you will now also immediately cause the creature to be tapped.
2936 if (effectUnit->IsInCombatWith(m_caster))
2937 {
2938 if (Creature* creature = effectUnit->ToCreature())
2939 {
2940 if (!creature->hasLootRecipient() && m_caster->IsPlayer())
2941 {
2942 creature->SetLootRecipient(m_caster);
2943 }
2944 }
2945 }
2946
2947 // Unsure if there are more spells that are not supposed to stop enemy from
2948 // regenerating HP from food, so for now it stays as an ID.
2949 const uint32 SPELL_PREMEDITATION = 14183;
2950 if (m_spellInfo->Id != SPELL_PREMEDITATION)
2951 {
2952 if (!effectUnit->IsStandState())
2953 {
2955 }
2956 }
2957 }
2958 }
2959
2960 if (missInfo != SPELL_MISS_EVADE && effectUnit != m_caster && m_caster->IsFriendlyTo(effectUnit) && m_spellInfo->IsPositive() &&
2962 {
2963 m_caster->SetInCombatWith(effectUnit);
2964 }
2965
2966 // Check for SPELL_ATTR7_CAN_CAUSE_INTERRUPT
2968 caster->CastSpell(effectUnit, SPELL_INTERRUPT_NONPLAYER, true);
2969
2970 if (spellHitTarget)
2971 {
2972 //AI functions
2973 if (spellHitTarget->GetTypeId() == TYPEID_UNIT)
2974 {
2975 if (spellHitTarget->ToCreature()->IsAIEnabled)
2976 spellHitTarget->ToCreature()->AI()->SpellHit(m_caster, m_spellInfo);
2977 }
2978
2980 m_caster->ToCreature()->AI()->SpellHitTarget(spellHitTarget, m_spellInfo);
2981
2982 // Needs to be called after dealing damage/healing to not remove breaking on damage auras
2983 DoTriggersOnSpellHit(spellHitTarget, mask);
2984
2985 // if target is fallged for pvp also flag caster if a player
2986 // xinef: do not flag spells with aura bind sight (no special attribute)
2987 if (effectUnit->IsPvP() && effectUnit != m_caster && effectUnit->GetOwnerGUID() != m_caster->GetGUID() &&
2989 {
2990 m_caster->ToPlayer()->UpdatePvP(true);
2991 }
2992
2994 }
2995}
uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition)
Definition: Unit.cpp:15909
@ NODAMAGE
Definition: Unit.h:252
@ SPELL_DIRECT_DAMAGE
Definition: Unit.h:249
@ HEAL
Definition: Unit.h:251
@ UNIT_STAND_STATE_STAND
Definition: UnitDefines.h:32
static const uint32 SPELL_INTERRUPT_NONPLAYER
Definition: Spell.h:267
@ AURA_INTERRUPT_FLAG_TALK
Definition: SpellDefines.h:54
@ SPELL_ATTR0_CU_NO_PVP_FLAG
Definition: SpellInfo.h:183
@ SPELL_ATTR0_CU_PICKPOCKET
Definition: SpellInfo.h:186
@ PROC_EX_NO_OVERHEAL
Definition: SpellMgr.h:213
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG
Definition: SpellMgr.h:132
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG
Definition: SpellMgr.h:126
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS
Definition: SpellMgr.h:129
@ PROC_FLAG_TAKEN_DAMAGE
Definition: SpellMgr.h:137
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS
Definition: SpellMgr.h:123
@ SPELL_EFFECT_HEALTH_LEECH
Definition: SharedDefines.h:787
@ SPELL_ATTR1_NO_THREAT
Definition: SharedDefines.h:429
@ SPELL_ATTR3_SUPRESS_CASTER_PROCS
Definition: SharedDefines.h:509
@ SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT
Definition: SharedDefines.h:402
@ SPELL_HIT_TYPE_CRIT
Definition: SharedDefines.h:1536
SpellMissInfo
Definition: SharedDefines.h:1518
@ SPELL_MISS_DODGE
Definition: SharedDefines.h:1522
@ SPELL_MISS_IMMUNE2
Definition: SharedDefines.h:1527
@ SPELL_MISS_RESIST
Definition: SharedDefines.h:1521
@ SPELL_MISS_MISS
Definition: SharedDefines.h:1520
@ SPELL_MISS_BLOCK
Definition: SharedDefines.h:1524
@ SPELL_ATTR4_SUPRESS_WEAPON_PROCS
Definition: SharedDefines.h:553
Milliseconds GetGameTimeMS()
Definition: GameTime.cpp:43
virtual void AttackStart(Unit *)
Definition: UnitAI.cpp:27
virtual void SpellHitTarget(Unit *, SpellInfo const *)
Definition: CreatureAI.h:146
virtual void SpellHit(Unit *, SpellInfo const *)
Definition: CreatureAI.h:143
void threatAssist(Unit *victim, float baseThreat, SpellInfo const *threatSpell=nullptr)
Definition: HostileRefMgr.cpp:35
void LowerPlayerDamageReq(uint32 unDamage, bool damagedByPlayer=true)
Definition: Creature.cpp:3765
CreatureAI * AI() const
Definition: Creature.h:137
bool IsPlayer() const
Definition: Object.h:197
void RestoreSpellMods(Spell *spell, uint32 ownerAuraId=0, Aura *aura=nullptr)
Definition: Player.cpp:9891
void CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx)
Definition: Player.cpp:7155
void UpdatePvP(bool state, bool _override=false)
Definition: PlayerUpdates.cpp:1480
Definition: Unit.h:330
Definition: Unit.h:373
Definition: Unit.h:489
uint32 m_lastSanctuaryTime
Definition: Unit.h:1479
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss, Spell const *spell=nullptr)
Definition: Unit.cpp:1422
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
Definition: Unit.cpp:6390
void SendSpellNonMeleeReflectLog(SpellNonMeleeDamage *log, Unit *attacker)
Definition: Unit.cpp:6223
bool CanProc()
Definition: Unit.h:1662
bool IsPvP() const
Definition: Unit.h:861
uint32 SpellHealingBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition: Unit.cpp:12374
void SetInCombatWith(Unit *enemy, uint32 duration=0)
Definition: Unit.cpp:13503
int32 HealBySpell(HealInfo &healInfo, bool critical=false)
Definition: Unit.cpp:11166
bool IsStandState() const
Definition: Unit.cpp:16635
bool IsInCombatWith(Unit const *who) const
Definition: Unit.cpp:20918
HostileRefMgr & getHostileRefMgr()
Definition: Unit.h:1491
int32 GetHealthGain(int32 dVal)
Definition: Unit.cpp:14039
static uint32 SpellCriticalHealingBonus(Unit const *caster, SpellInfo const *spellProto, uint32 damage, Unit const *victim)
Definition: Unit.cpp:12243
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
Definition: Unit.cpp:6255
bool IsAIEnabled
Definition: Unit.h:1692
void SetLastDamagedTargetGuid(ObjectGuid const &guid)
Definition: Unit.h:916
uint32 SpellHealingBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack=1)
Definition: Unit.cpp:12492
void SetStandState(uint8 state)
Definition: Unit.cpp:16641
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition: Unit.cpp:5126
static void DealDamageMods(Unit const *victim, uint32 &damage, uint32 *absorb)
Definition: Unit.cpp:787
void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType=BASE_ATTACK, bool crit=false)
Definition: Unit.cpp:1279
ObjectGuid GetUnitTargetGUID() const
Definition: Spell.cpp:216
bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
Definition: Spell.cpp:8720
SpellValue const * GetSpellValue()
Definition: Spell.h:583
SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask, bool scaleAura)
Definition: Spell.cpp:2997
void DoTriggersOnSpellHit(Unit *unit, uint8 effMask)
Definition: Spell.cpp:3255
uint32 AttributesEx3
Definition: SpellInfo.h:327
bool IsTargetingArea() const
Definition: SpellInfo.cpp:1024
bool IsPositiveEffect(uint8 effIndex) const
Definition: SpellInfo.cpp:1241

References SpellNonMeleeDamage::absorb, Creature::AI(), TargetInfo::alive, UnitAI::AttackStart(), SpellInfo::AttributesEx3, AURA_INTERRUPT_FLAG_TALK, SpellNonMeleeDamage::blocked, Unit::CalculateSpellDamageTaken(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), CanExecuteTriggersOnHit(), Unit::CanProc(), Player::CastItemCombatSpell(), Unit::CastSpell(), Unit::CombatStart(), createProcExtendMask(), TargetInfo::crit, SpellNonMeleeDamage::damage, TargetInfo::damage, Unit::DealDamageMods(), Unit::DealSpellDamage(), SpellInfo::DmgClass, DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EFFECT_0, TriggeredByAuraSpellData::effectIndex, TargetInfo::effectMask, SpellInfo::Effects, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), Object::GetEntry(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::GetHealthGain(), Unit::getHostileRefMgr(), Unit::GetOwner(), Unit::GetOwnerGUID(), SpellInfo::GetSchoolMask(), GetSpellValue(), getState(), Object::GetTypeId(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTargetGUID(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), HEAL, Unit::HealBySpell(), SpellNonMeleeDamage::HitInfo, SpellInfo::Id, Unit::IsAIEnabled, Unit::IsAlive(), Map::IsDungeon(), Unit::IsFriendlyTo(), Unit::IsInCombat(), Unit::IsInCombatWith(), Object::IsPlayer(), ObjectGuid::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsPvP(), Unit::IsStandState(), SpellInfo::IsTargetingArea(), Creature::LowerPlayerDamageReq(), m_attackType, m_caster, m_damage, m_healing, Unit::m_lastSanctuaryTime, m_needComboPoints, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_spellAura, m_spellInfo, m_spellSchoolMask, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, TargetInfo::missCondition, NODAMAGE, PrepareScriptHitHandlers(), PROC_EX_CRITICAL_HIT, PROC_EX_NO_OVERHEAL, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_TAKEN_DAMAGE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS, Unit::ProcDamageAndSpell(), TargetInfo::processed, TargetInfo::reflectResult, Unit::RemoveAurasWithInterruptFlags(), Player::RestoreSpellMods(), TargetInfo::scaleAura, Unit::SendSpellMiss(), Unit::SendSpellNonMeleeDamageLog(), Unit::SendSpellNonMeleeReflectLog(), Unit::SetInCombatWith(), Unit::SetLastDamagedTargetGuid(), Unit::SetStandState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR0_CU_PICKPOCKET, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPRESS_CASTER_PROCS, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_ATTR4_SUPRESS_WEAPON_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_NONE, SPELL_DAMAGE_CLASS_RANGED, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HEALTH_LEECH, SPELL_HIT_TYPE_CRIT, SPELL_INTERRUPT_NONPLAYER, SPELL_MISS_BLOCK, SPELL_MISS_DODGE, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE2, SPELL_MISS_MISS, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, SPELL_MISS_RESIST, SPELL_STATE_DELAYED, Unit::SpellCriticalHealingBonus(), Unit::SpellHealingBonusDone(), Unit::SpellHealingBonusTaken(), CreatureAI::SpellHit(), CreatureAI::SpellHitTarget(), TriggeredByAuraSpellData::spellInfo, SpellNonMeleeDamage::target, TargetInfo::targetGUID, HostileRefMgr::threatAssist(), TargetInfo::timeDelay, Object::ToCreature(), Object::ToPlayer(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_STAND_STATE_STAND, unitTarget, and Player::UpdatePvP().

Referenced by _handle_immediate_phase(), handle_delayed(), and handle_immediate().

◆ DoCreateItem()

void Spell::DoCreateItem ( uint8  effIndex,
uint32  itemId 
)
1636{
1637 if (!unitTarget)
1638 return;
1639
1640 Player* player = unitTarget->ToPlayer();
1641 if (!player)
1642 {
1643 return;
1644 }
1645
1646 uint32 newitemid = itemId;
1647
1648 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid);
1649 if (!pProto)
1650 {
1651 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1652 return;
1653 }
1654
1655 uint32 addNumber = damage;
1656
1657 // bg reward have some special in code work
1658 bool SelfCast = true;
1659 switch (m_spellInfo->Id)
1660 {
1665 case SPELL_WS_MARK_TIE:
1668 SelfCast = true;
1669 break;
1671 if (player->HasAura(55629 /*SPELL_LIEUTENANT*/))
1672 addNumber = 3;
1673 else if (player->HasAura(33280 /*SPELL_CORPORAL*/))
1674 addNumber = 2;
1675 else
1676 addNumber = 1;
1677 SelfCast = true;
1678 break;
1679 }
1680
1681 if (addNumber < 1)
1682 addNumber = 1;
1683 if (addNumber > pProto->GetMaxStackSize())
1684 addNumber = pProto->GetMaxStackSize();
1685
1686 /* == gem perfection handling == */
1687
1688 // the chance of getting a perfect result
1689 float perfectCreateChance = 0.0f;
1690
1691 // the resulting perfect item if successful
1692 uint32 perfectItemType = itemId;
1693
1694 // get perfection capability and chance
1695 if (CanCreatePerfectItem(player, m_spellInfo->Id, perfectCreateChance, perfectItemType))
1696 if (roll_chance_f(perfectCreateChance)) // if the roll succeeds...
1697 newitemid = perfectItemType; // the perfect item replaces the regular one
1698
1699 /* == gem perfection handling over == */
1700
1701 /* == profession specialization handling == */
1702
1703 // init items_count to 1, since 1 item will be created regardless of specialization
1704 int32 itemsCount = 1;
1705 float additionalCreateChance = 0.0f;
1706 int32 additionalMaxNum = 0;
1707 // get the chance and maximum number for creating extra items
1708 if (canCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum))
1709 {
1710 // roll with this chance till we roll not to create or we create the max num
1711 while (roll_chance_f(additionalCreateChance) && itemsCount <= additionalMaxNum)
1712 ++itemsCount;
1713 }
1714
1715 // really will be created more items
1716 addNumber *= itemsCount;
1717
1718 /* == profession specialization handling over == */
1719
1720 // can the player store the new item?
1721 ItemPosCountVec dest;
1722 uint32 no_space = 0;
1723 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, newitemid, addNumber, &no_space);
1724 if (msg != EQUIP_ERR_OK)
1725 {
1726 // convert to possible store amount
1728 addNumber -= no_space;
1729 else
1730 {
1731 // if not created by another reason from full inventory or unique items amount limitation
1732 player->SendEquipError(msg, nullptr, nullptr, newitemid);
1733 return;
1734 }
1735 }
1736
1737 if (addNumber)
1738 {
1739 // create the new item and store it
1740 Item* pItem = player->StoreNewItem(dest, newitemid, true);
1741
1742 // was it successful? return error if not
1743 if (!pItem)
1744 {
1745 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1746 return;
1747 }
1748
1749 // set the "Crafted by ..." property of the item
1750 if (pItem->GetTemplate()->HasSignature())
1751 pItem->SetGuidValue(ITEM_FIELD_CREATOR, player->GetGUID());
1752
1753 // send info to the client
1754 player->SendNewItem(pItem, addNumber, true, SelfCast);
1755
1756 sScriptMgr->OnCreateItem(player, pItem, addNumber);
1757
1758 // we succeeded in creating at least one item, so a levelup is possible
1759 if (SelfCast)
1761 }
1762}
@ SPELL_WS_MARK_WINNER
Definition: Battleground.h:101
@ SPELL_AV_MARK_LOSER
Definition: Battleground.h:105
@ SPELL_WS_MARK_TIE
Definition: Battleground.h:102
@ SPELL_WS_MARK_LOSER
Definition: Battleground.h:100
@ SPELL_AB_MARK_LOSER
Definition: Battleground.h:103
@ SPELL_WG_MARK_WINNER
Definition: Battleground.h:109
@ SPELL_AB_MARK_WINNER
Definition: Battleground.h:104
@ SPELL_AV_MARK_WINNER
Definition: Battleground.h:106
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition: Item.h:70
@ EQUIP_ERR_CANT_CARRY_MORE_OF_THIS
Definition: Item.h:64
@ ITEM_FIELD_CREATOR
Definition: UpdateFields.h:37
bool canCreateExtraItems(Player *player, uint32 spellId, float &additionalChance, int32 &newMaxOrEntry)
Definition: SkillExtraItems.cpp:226
bool CanCreatePerfectItem(Player *player, uint32 spellId, float &perfectCreateChance, uint32 &perfectItemType)
Definition: SkillExtraItems.cpp:202
bool HasSignature() const
Definition: ItemTemplate.h:706
void SetGuidValue(uint16 index, ObjectGuid value)
Definition: Object.cpp:723
bool UpdateCraftSkill(uint32 spellid)
Definition: PlayerUpdates.cpp:781
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false, bool sendChatMessage=true)
Definition: PlayerStorage.cpp:4765
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0)
Definition: PlayerStorage.cpp:2539

References canCreateExtraItems(), CanCreatePerfectItem(), Player::CanStoreNewItem(), damage, EQUIP_ERR_CANT_CARRY_MORE_OF_THIS, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_OK, Object::GetGUID(), ItemTemplate::GetMaxStackSize(), Item::GetTemplate(), Unit::HasAura(), ItemTemplate::HasSignature(), SpellInfo::Id, ITEM_FIELD_CREATOR, m_spellInfo, NULL_BAG, NULL_SLOT, roll_chance_f(), Player::SendEquipError(), Player::SendNewItem(), Object::SetGuidValue(), sObjectMgr, SPELL_AB_MARK_LOSER, SPELL_AB_MARK_WINNER, SPELL_AV_MARK_LOSER, SPELL_AV_MARK_WINNER, SPELL_WG_MARK_WINNER, SPELL_WS_MARK_LOSER, SPELL_WS_MARK_TIE, SPELL_WS_MARK_WINNER, sScriptMgr, Player::StoreNewItem(), Object::ToPlayer(), unitTarget, and Player::UpdateCraftSkill().

Referenced by SpellScript::CreateItem(), EffectCreateItem(), EffectCreateItem2(), and EffectEnchantItemPerm().

◆ DoSpellHitOnUnit()

SpellMissInfo Spell::DoSpellHitOnUnit ( Unit unit,
uint32  effectMask,
bool  scaleAura 
)
protected
Todo:
: this cause soul transfer bugged
2998{
2999 if (!unit || !effectMask)
3000 return SPELL_MISS_EVADE;
3001
3002 // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
3003 if (m_spellInfo->Speed && ((m_damage > 0 && unit->IsImmunedToDamage(this)) || unit->IsImmunedToSchool(this) || unit->IsImmunedToSpell(m_spellInfo, this)))
3004 {
3005 return SPELL_MISS_IMMUNE;
3006 }
3007
3008 // disable effects to which unit is immune
3009 SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
3010 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3011 {
3012 if (effectMask & (1 << effectNumber))
3013 {
3014 if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber))
3015 effectMask &= ~(1 << effectNumber);
3016 // Xinef: Buggs out polymorph
3017 // Xinef: And this is checked in MagicSpellHitResult, why we check resistance twice?
3018 // Xinef: And why we check every spell effect basing on rand and generic dispel info? some effects will be appliend and some wont?
3019 /*else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
3020 {
3021 int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3022 debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3023
3024 if (debuff_resist_chance > 0)
3025 if (irand(0,10000) <= (debuff_resist_chance * 100))
3026 {
3027 effectMask &= ~(1 << effectNumber);
3028 returnVal = SPELL_MISS_RESIST;
3029 }
3030 }*/
3031 }
3032 }
3033 if (!effectMask)
3034 return returnVal;
3035
3036 if (unit->GetTypeId() == TYPEID_PLAYER)
3037 {
3041 }
3042
3044 {
3047 }
3048
3049 if (m_caster != unit)
3050 {
3051 // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
3052 // Xinef: Also check evade state
3053 if (m_spellInfo->Speed > 0.0f)
3054 {
3055 if (unit->GetTypeId() == TYPEID_UNIT && unit->ToCreature()->IsInEvadeMode())
3056 return SPELL_MISS_EVADE;
3057
3059 return SPELL_MISS_EVADE;
3060 }
3061
3062 if (m_caster->_IsValidAttackTarget(unit, m_spellInfo) && /*Intervene Trigger*/ m_spellInfo->Id != 59667)
3063 {
3065 }
3066 else if (m_caster->IsFriendlyTo(unit))
3067 {
3068 // for delayed spells ignore negative spells (after duel end) for friendly targets
3070 if(!IsTriggered() && m_spellInfo->Speed > 0.0f && unit->GetTypeId() == TYPEID_PLAYER && !m_spellInfo->IsPositive())
3071 return SPELL_MISS_EVADE;
3072
3073 // assisting case, healing and resurrection
3075 {
3078 m_caster->ToPlayer()->UpdatePvP(true);
3079 }
3080
3081 // xinef: triggered spells should not prolong combat
3083 {
3084 m_caster->SetInCombatState(unit->GetCombatTimer() > 0, unit);
3085 unit->getHostileRefMgr().threatAssist(m_caster, 0.0f);
3086 }
3087 }
3088 }
3089
3090 uint8 aura_effmask = 0;
3091 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3092 if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
3093 aura_effmask |= 1 << i;
3094
3095 Unit* originalCaster = GetOriginalCaster();
3096 if (!originalCaster)
3097 originalCaster = m_caster;
3098
3099 // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
3100 // Xinef: Do not increase diminishing level for self cast
3102 // xinef: do not increase diminish level for bosses (eg. Void Reaver silence is never diminished)
3104 {
3107
3108 uint32 flagsExtra = unit->GetTypeId() == TYPEID_UNIT ? unit->ToCreature()->GetCreatureTemplate()->flags_extra : 0;
3109
3110 // Increase Diminishing on unit, current informations for actually casts will use values above
3111 if ((type == DRTYPE_PLAYER && (unit->IsCharmedOwnedByPlayerOrPlayer() || flagsExtra & CREATURE_FLAG_EXTRA_ALL_DIMINISH ||
3113 {
3114 // Do not apply diminish return if caster is NPC
3116 {
3118 }
3119 }
3120 }
3121
3123 {
3125 }
3126
3127 if (aura_effmask)
3128 {
3129 // Select rank for aura with level requirements only in specific cases
3130 // Unit has to be target only of aura effect, both caster and target have to be players, target has to be other than unit target
3131 SpellInfo const* aurSpellInfo = m_spellInfo;
3132 int32 basePoints[3];
3133 if (scaleAura)
3134 {
3136 ASSERT(aurSpellInfo);
3137 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3138 {
3139 basePoints[i] = aurSpellInfo->Effects[i].BasePoints;
3140 if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect)
3141 {
3142 aurSpellInfo = m_spellInfo;
3143 break;
3144 }
3145 }
3146 }
3147
3148 if (m_originalCaster)
3149 {
3150 bool refresh = false;
3152 m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit, m_originalCaster,
3153 (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh, refreshPeriodic);
3154
3155 // xinef: if aura was not refreshed, add proc ex
3156 if (!refresh)
3158
3159 if (m_spellAura)
3160 {
3161 // Set aura stack amount to desired value
3163 {
3164 if (!refresh)
3166 else
3168 }
3169
3170 // Now Reduce spell duration using data received at spell hit
3171 int32 duration = m_spellAura->GetMaxDuration();
3172 int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, aurSpellInfo);
3173
3174 // Xinef: if unit == caster - test versus original unit if available
3175 float diminishMod = 1.0f;
3176 if (unit == m_caster && m_targets.GetUnitTarget())
3178 else
3179 diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel, limitduration);
3180
3181 // unit is immune to aura if it was diminished to 0 duration
3182 if (diminishMod == 0.0f)
3183 {
3186 return SPELL_MISS_IMMUNE;
3187 bool found = false;
3188 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3189 if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA)
3190 found = true;
3191 if (!found)
3192 return SPELL_MISS_IMMUNE;
3193 }
3194 else
3195 {
3196 ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
3197
3198 bool positive = m_spellAura->GetSpellInfo()->IsPositive();
3200 positive = aurApp->IsPositive();
3201
3202 duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
3203
3204 // xinef: haste affects duration of those spells twice
3207
3208 if (m_spellValue->AuraDuration != 0)
3209 {
3210 if (m_spellAura->GetMaxDuration() != -1)
3211 {
3213 }
3214
3216 }
3217 else if (duration != m_spellAura->GetMaxDuration())
3218 {
3219 m_spellAura->SetMaxDuration(duration);
3220 m_spellAura->SetDuration(duration);
3221 }
3222
3223 // xinef: apply relic cooldown, imo best place to add this
3226
3229 }
3230 }
3231 }
3232 }
3233
3234 int8 sanct_effect = -1;
3235
3236 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3237 {
3238 // handle sanctuary effects after aura apply!
3239 if (m_spellInfo->Effects[effectNumber].Effect == SPELL_EFFECT_SANCTUARY)
3240 {
3241 sanct_effect = effectNumber;
3242 continue;
3243 }
3244
3245 if (effectMask & (1 << effectNumber))
3246 HandleEffects(unit, nullptr, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3247 }
3248
3249 if( sanct_effect >= 0 && (effectMask & (1 << sanct_effect)) )
3250 HandleEffects(unit, nullptr, nullptr, sanct_effect, SPELL_EFFECT_HANDLE_HIT_TARGET);
3251
3252 return SPELL_MISS_NONE;
3253}
@ CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS
Definition: CreatureData.h:65
@ CREATURE_FLAG_EXTRA_ALL_DIMINISH
Definition: CreatureData.h:66
@ UNIT_MOD_CAST_SPEED
Definition: UpdateFields.h:137
@ UNIT_STATE_ATTACK_PLAYER
Definition: UnitDefines.h:163
@ UNIT_FLAG_NON_ATTACKABLE
Definition: UnitDefines.h:230
@ SPELL_AURA_PERIODIC_HASTE
Definition: SpellAuraDefines.h:379
@ SPELL_AURA_REFLECT_SPELLS
Definition: SpellAuraDefines.h:91
@ SPELL_AURA_MOD_STEALTH
Definition: SpellAuraDefines.h:79
@ AURA_INTERRUPT_FLAG_HITBYSPELL
Definition: SpellDefines.h:44
@ TRIGGERED_NO_PERIODIC_RESET
Will ignore equipped item requirements.
Definition: SpellDefines.h:150
@ SPELL_ATTR0_CU_DONT_BREAK_STEALTH
Definition: SpellInfo.h:182
int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellInfo const *spellproto)
Definition: SpellMgr.cpp:276
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const *spellproto, bool triggered)
Definition: SpellMgr.cpp:59
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
Definition: SpellMgr.cpp:246
@ PROC_EX_NO_AURA_REFRESH
Definition: SpellMgr.h:214
@ ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER
Definition: DBCEnums.h:112
@ ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET
Definition: DBCEnums.h:113
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2
Definition: DBCEnums.h:181
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET
Definition: DBCEnums.h:142
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2
Definition: DBCEnums.h:217
@ DIMINISHING_TAUNT
Definition: SharedDefines.h:3276
@ SPELL_EFFECT_SANCTUARY
Definition: SharedDefines.h:857
@ SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC
Definition: SharedDefines.h:580
DiminishingReturnsType
Definition: SharedDefines.h:3249
@ DRTYPE_PLAYER
Definition: SharedDefines.h:3251
@ DRTYPE_ALL
Definition: SharedDefines.h:3252
bool isWorldBoss() const
Definition: Creature.h:117
bool IsInEvadeMode() const
Definition: Creature.h:131
uint32 flags_extra
Definition: CreatureData.h:249
float GetFloatValue(uint16 index) const
Definition: Object.cpp:317
static ObjectGuid const Empty
Definition: ObjectGuid.h:120
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition: Unit.cpp:5683
DiminishingLevels GetDiminishing(DiminishingGroup group)
Definition: Unit.cpp:14921
void IncrDiminishing(DiminishingGroup group)
Definition: Unit.cpp:14947
uint32 GetCombatTimer() const
Definition: Unit.h:1041
bool IsImmunedToSchool(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12754
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition: Unit.cpp:17163
bool HasUnitFlag(UnitFlags flags) const
Definition: Unit.h:824
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
Definition: Unit.cpp:14961
int32 ModSpellDuration(SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask)
Definition: Unit.cpp:14787
virtual void AddSpellCooldown(uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
Definition: Unit.h:1762
void SetInCombatState(bool PvP, Unit *enemy=nullptr, uint32 duration=0)
Definition: Unit.cpp:13650
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition: Unit.h:1180
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:5650
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12669
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, Spell const *spell=nullptr)
Definition: Unit.cpp:12838
bool IsHostileTo(Unit const *unit) const
Definition: Unit.cpp:10172
bool _IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell, WorldObject const *obj=nullptr) const
Definition: Unit.cpp:13793
ObjectGuid GetCharmerOrOwnerGUID() const
Definition: Unit.h:1172
Definition: SpellAuras.h:37
int32 GetMaxDuration() const
Definition: SpellAuras.h:129
void SetStackAmount(uint8 num)
Definition: SpellAuras.cpp:995
void SetTriggeredByAuraSpellInfo(SpellInfo const *triggeredByAuraSpellInfo)
Definition: SpellAuras.cpp:2747
void _RegisterForTargets()
Definition: SpellAuras.h:121
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool periodicReset=false)
Definition: SpellAuras.cpp:1021
static Aura * TryRefreshStackOrCreate(SpellInfo const *spellproto, uint8 tryEffMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, bool *refresh=nullptr, bool periodicReset=false)
Definition: SpellAuras.cpp:326
void SetDuration(int32 duration, bool withMods=false)
Definition: SpellAuras.cpp:868
const AuraApplication * GetApplicationOfTarget(ObjectGuid guid) const
Definition: SpellAuras.h:183
void SetMaxDuration(int32 duration)
Definition: SpellAuras.h:130
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
Definition: SpellAuras.h:279
int32 AuraDuration
Definition: Spell.h:217
uint8 AuraStackAmount
Definition: Spell.h:216
Unit * GetOriginalCaster() const
Definition: Spell.h:574
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition: SpellInfo.cpp:2525

References Unit::_IsValidAttackTarget(), Aura::_RegisterForTargets(), ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER, ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, Unit::AddSpellCooldown(), Unit::ApplyDiminishingToDuration(), ASSERT, AURA_INTERRUPT_FLAG_HITBYSPELL, SpellValue::AuraDuration, SpellValue::AuraStackAmount, CREATURE_FLAG_EXTRA_ALL_DIMINISH, CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS, DIMINISHING_TAUNT, DRTYPE_ALL, DRTYPE_PLAYER, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, CreatureTemplate::flags_extra, Aura::GetApplicationOfTarget(), SpellInfo::GetAuraRankForLevel(), Unit::GetCharmerOrOwnerGUID(), Unit::GetCombatTimer(), Creature::GetCreatureTemplate(), Unit::GetDiminishing(), GetDiminishingReturnsGroupForSpell(), GetDiminishingReturnsGroupType(), GetDiminishingReturnsLimitDuration(), Object::GetEntry(), Object::GetFloatValue(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetLevel(), Aura::GetMaxDuration(), GetOriginalCaster(), Aura::GetSpellInfo(), Item::GetTemplate(), Object::GetTypeId(), SpellCastTargets::GetUnitTarget(), HandleEffects(), SpellInfo::HasAttribute(), Unit::HasAuraType(), Unit::HasAuraTypeWithAffectMask(), HasTriggeredCastFlag(), Unit::HasUnitFlag(), Unit::HasUnitState(), SpellInfo::Id, Unit::IncrDiminishing(), ItemTemplate::InventoryType, INVTYPE_RELIC, Unit::IsCharmedOwnedByPlayerOrPlayer(), Unit::IsFriendlyTo(), Unit::IsHostileTo(), Unit::IsImmunedToDamage(), Unit::IsImmunedToSchool(), Unit::IsImmunedToSpell(), Unit::IsImmunedToSpellEffect(), Unit::IsInCombat(), Creature::IsInEvadeMode(), SpellInfo::IsPositive(), IsTriggered(), Creature::isWorldBoss(), m_caster, m_CastItem, m_damage, m_diminishGroup, m_diminishLevel, m_originalCaster, m_procEx, m_spellAura, m_spellFlags, m_spellInfo, m_spellValue, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, Unit::ModSpellDuration(), Aura::ModStackAmount(), PROC_EX_NO_AURA_REFRESH, Aura::Remove(), Unit::RemoveAurasByType(), Unit::RemoveAurasWithInterruptFlags(), Unit::SetContestedPvP(), Aura::SetDuration(), Unit::SetInCombatState(), Aura::SetMaxDuration(), Aura::SetStackAmount(), Aura::SetTriggeredByAuraSpellInfo(), SpellInfo::Speed, SPELL_ATTR0_CU_DONT_BREAK_STEALTH, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_MOD_STEALTH, SPELL_AURA_PERIODIC_HASTE, SPELL_AURA_REFLECT_SPELLS, SPELL_EFFECT_APPLY_AURA, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_SANCTUARY, SPELL_FLAG_REFLECTED, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_RELIC_COOLDOWN, TriggeredByAuraSpellData::spellInfo, SpellInfo::StackAmount, Player::StartTimedAchievement(), HostileRefMgr::threatAssist(), Object::ToCreature(), Object::ToPlayer(), TRIGGERED_NO_PERIODIC_RESET, Aura::TryRefreshStackOrCreate(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_FLAG_NON_ATTACKABLE, UNIT_MOD_CAST_SPEED, UNIT_STATE_ATTACK_PLAYER, unitTarget, Player::UpdateAchievementCriteria(), and Player::UpdatePvP().

Referenced by DoAllEffectOnTarget().

◆ DoTriggersOnSpellHit()

void Spell::DoTriggersOnSpellHit ( Unit unit,
uint8  effMask 
)
protected
Todo:
: move this code to scripts
Todo:
: remove/cleanup this, as this table is not documented and people are doing stupid things with it
3256{
3257 // Apply additional spell effects to target
3259 if (m_preCastSpell)
3260 {
3261 // Paladin immunity shields
3262 if (m_preCastSpell == 61988)
3263 {
3264 // Cast Forbearance
3265 m_caster->CastSpell(unit, 25771, true);
3266 // Cast Avenging Wrath Marker
3267 unit->CastSpell(unit, 61987, true);
3268 }
3269
3270 // Avenging Wrath
3271 if (m_preCastSpell == 61987)
3272 // Cast the serverside immunity shield marker
3273 m_caster->CastSpell(unit, 61988, true);
3274
3275 // Fearie Fire (Feral) - damage
3276 if( m_preCastSpell == 60089 )
3277 m_caster->CastSpell(unit, m_preCastSpell, true);
3278 else if (sSpellMgr->GetSpellInfo(m_preCastSpell))
3279 // Blizz seems to just apply aura without bothering to cast
3281 }
3282
3283 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
3284 // this is executed after spell proc spells on target hit
3285 // spells are triggered for each hit spell target
3286 // info confirmed with retail sniffs of permafrost and shadow weaving
3287 if (!m_hitTriggerSpells.empty())
3288 {
3289 int _duration = 0;
3290 for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
3291 {
3292 if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
3293 {
3294 m_caster->CastSpell(unit, i->triggeredSpell->Id, true);
3295 LOG_DEBUG("spells.aura", "Spell {} triggered spell {} by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
3296
3297 // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
3298 // set duration of current aura to the triggered spell
3299 if (i->triggeredSpell->GetDuration() == -1)
3300 {
3301 if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID()))
3302 {
3303 // get duration from aura-only once
3304 if (!_duration)
3305 {
3306 Aura* aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
3307 _duration = aur ? aur->GetDuration() : -1;
3308 }
3309 triggeredAur->SetDuration(_duration);
3310 }
3311 }
3312 }
3313 }
3314 }
3315
3316 // trigger linked auras remove/apply
3318 if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id + SPELL_LINK_HIT))
3319 {
3320 for (std::vector<int32>::const_iterator i = spellTriggered->begin(); i != spellTriggered->end(); ++i)
3321 if (*i < 0)
3322 {
3323 unit->RemoveAurasDueToSpell(-(*i));
3324 }
3325 else
3326 {
3327 unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID());
3328 }
3329 }
3330}
bool roll_chance_i(int chance)
Definition: Random.h:59
@ SPELL_LINK_HIT
Definition: SpellMgr.h:97
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:5526
Aura * AddAura(uint32 spellId, Unit *target)
Definition: Unit.cpp:18767
int32 GetDuration() const
Definition: SpellAuras.h:133
HitTriggerSpellList m_hitTriggerSpells
Definition: Spell.h:754

References Unit::AddAura(), CanExecuteTriggersOnHit(), Unit::CastSpell(), Unit::GetAura(), Aura::GetDuration(), Object::GetGUID(), SpellInfo::Id, LOG_DEBUG, m_caster, m_hitTriggerSpells, m_preCastSpell, m_spellInfo, Unit::RemoveAurasDueToSpell(), roll_chance_i(), SPELL_LINK_HIT, and sSpellMgr.

Referenced by DoAllEffectOnTarget().

◆ EffectActivateObject()

void Spell::EffectActivateObject ( SpellEffIndex  effIndex)
4232{
4234 return;
4235
4236 if (!gameObjTarget)
4237 return;
4238
4239 GameObjectActions action = GameObjectActions(m_spellInfo->Effects[effIndex].MiscValue);
4240 switch (action)
4241 {
4242 case GameObjectActions::AnimateCustom0:
4243 case GameObjectActions::AnimateCustom1:
4244 case GameObjectActions::AnimateCustom2:
4245 case GameObjectActions::AnimateCustom3:
4246 gameObjTarget->SendCustomAnim(uint32(action) - uint32(GameObjectActions::AnimateCustom0));
4247 break;
4248 case GameObjectActions::Disturb: // What's the difference with Open?
4249 case GameObjectActions::Open:
4250 if (Unit* unitCaster = m_caster->ToUnit())
4251 gameObjTarget->Use(unitCaster);
4252 break;
4253 case GameObjectActions::OpenAndUnlock:
4254 if (Unit* unitCaster = m_caster->ToUnit())
4255 gameObjTarget->UseDoorOrButton(0, false, unitCaster);
4256 [[fallthrough]];
4257 case GameObjectActions::Unlock:
4258 case GameObjectActions::Lock:
4259 gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED, action == GameObjectActions::Lock);
4260 break;
4261 case GameObjectActions::Close:
4262 case GameObjectActions::Rebuild:
4264 break;
4265 case GameObjectActions::Despawn:
4267 break;
4268 case GameObjectActions::MakeInert:
4269 case GameObjectActions::MakeActive:
4270 gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE, action == GameObjectActions::MakeInert);
4271 break;
4272 case GameObjectActions::CloseAndLock:
4275 break;
4276 case GameObjectActions::Destroy:
4277 if (Unit* unitCaster = m_caster->ToUnit())
4278 gameObjTarget->UseDoorOrButton(0, true, unitCaster);
4279 break;
4280 case GameObjectActions::UseArtKit0:
4281 case GameObjectActions::UseArtKit1:
4282 case GameObjectActions::UseArtKit2:
4283 case GameObjectActions::UseArtKit3:
4284 {
4285 GameObjectTemplateAddon const* templateAddon = gameObjTarget->GetTemplateAddon();
4286
4287 uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
4288
4289 uint32 artKitValue = 0;
4290 if (templateAddon)
4291 artKitValue = templateAddon->artKits[artKitIndex];
4292
4293 if (artKitValue == 0)
4294 LOG_ERROR("sql.sql", "GameObject {} hit by spell {} needs `artkit{}` in `gameobject_template_addon`", gameObjTarget->GetEntry(), m_spellInfo->Id, artKitIndex);
4295 else
4296 gameObjTarget->SetGoArtKit(artKitValue);
4297
4298 break;
4299 }
4300 case GameObjectActions::None:
4301 LOG_FATAL("spell", "Spell {} has action type NONE in effect {}", m_spellInfo->Id, int32(effIndex));
4302 break;
4303 default:
4304 LOG_ERROR("spell", "Spell {} has unhandled action {} in effect {}", m_spellInfo->Id, int32(action), int32(effIndex));
4305 break;
4306 }
4307}
#define LOG_FATAL(filterType__,...)
Definition: Log.h:152
GameObjectActions
Definition: GameObject.h:77
@ GAMEOBJECT_FLAGS
Definition: UpdateFields.h:399
@ GO_FLAG_NOT_SELECTABLE
Definition: SharedDefines.h:1607
@ GO_FLAG_LOCKED
Definition: SharedDefines.h:1604
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=nullptr)
Definition: GameObject.cpp:1429
void SetGoArtKit(uint8 artkit)
Definition: GameObject.cpp:1443
void SendCustomAnim(uint32 anim)
Definition: GameObject.cpp:2141
void ResetDoorOrButton()
Definition: GameObject.cpp:1419
void DespawnOrUnsummon(Milliseconds delay=0ms, Seconds forcedRespawnTime=0s)
Definition: GameObject.cpp:933
GameObjectTemplateAddon const * GetTemplateAddon() const
Definition: GameObject.cpp:912
void Use(Unit *user)
Definition: GameObject.cpp:1479
Definition: GameObjectData.h:665
std::array< uint32, 4 > artKits
Definition: GameObjectData.h:671
void SetFlag(uint16 index, uint32 newFlag)
Definition: Object.cpp:845
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition: Object.cpp:899

References Object::ApplyModFlag(), GameObjectTemplateAddon::artKits, GameObject::DespawnOrUnsummon(), effectHandleMode, SpellInfo::Effects, GAMEOBJECT_FLAGS, gameObjTarget, Object::GetEntry(), GameObject::GetTemplateAddon(), GO_FLAG_LOCKED, GO_FLAG_NOT_SELECTABLE, SpellInfo::Id, LOG_ERROR, LOG_FATAL, m_caster, m_spellInfo, GameObject::ResetDoorOrButton(), GameObject::SendCustomAnim(), Object::SetFlag(), GameObject::SetGoArtKit(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToUnit(), GameObject::Use(), and GameObject::UseDoorOrButton().

◆ EffectActivateRune()

void Spell::EffectActivateRune ( SpellEffIndex  effIndex)
5746{
5748 return;
5749
5751 return;
5752
5753 Player* player = m_caster->ToPlayer();
5754
5756 return;
5757
5758 // needed later
5760
5761 uint32 count = damage;
5762 if (count == 0) count = 1;
5763 for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j)
5764 {
5765 if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue))
5766 {
5767 if (m_spellInfo->Id == 45529)
5768 if (player->GetBaseRune(j) != RuneType(m_spellInfo->Effects[effIndex].MiscValueB))
5769 continue;
5770 player->SetRuneCooldown(j, 0);
5771 player->SetGracePeriod(j, player->IsInCombat()); // xinef: reset grace period
5772 --count;
5773 }
5774 }
5775
5776 // Blood Tap
5777 if (m_spellInfo->Id == 45529 && count > 0)
5778 {
5779 for (uint32 l = 0; l < MAX_RUNES && count > 0; ++l)
5780 {
5781 // Check if both runes are on cd as that is the only time when this needs to come into effect
5782 if ((player->GetRuneCooldown(l) && player->GetCurrentRune(l) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)) && (player->GetRuneCooldown(l + 1) && player->GetCurrentRune(l + 1) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)))
5783 {
5784 // Should always update the rune with the lowest cd
5785 if (player->GetRuneCooldown(l) >= player->GetRuneCooldown(l + 1))
5786 l++;
5787 player->SetRuneCooldown(l, 0);
5788 player->SetGracePeriod(l, player->IsInCombat()); // xinef: reset grace period
5789 --count;
5790 }
5791 else
5792 break;
5793 }
5794 }
5795
5796 // Empower rune weapon
5797 if (m_spellInfo->Id == 47568)
5798 {
5799 // Need to do this just once
5800 if (effIndex != 0)
5801 return;
5802
5803 for (uint32 i = 0; i < MAX_RUNES; ++i)
5804 {
5805 if (player->GetRuneCooldown(i) && (player->GetCurrentRune(i) == RUNE_FROST || player->GetCurrentRune(i) == RUNE_DEATH))
5806 {
5807 player->SetRuneCooldown(i, 0);
5808 player->SetGracePeriod(i, player->IsInCombat()); // xinef: reset grace period
5809 }
5810 }
5811 }
5812
5813 // is needed to push through to the client that the rune is active
5814 //player->ResyncRunes(MAX_RUNES);
5815 m_caster->CastSpell(m_caster, 47804, true);
5816}
@ RUNE_FROST
Definition: Player.h:411
void SetRuneCooldown(uint8 index, uint32 cooldown)
Definition: Player.h:2492
uint8 GetRunesState() const
Definition: Player.h:2481
void SetGracePeriod(uint8 index, uint32 period)
Definition: Player.h:2493
RuneType GetBaseRune(uint8 index) const
Definition: Player.h:2482

References Unit::CastSpell(), CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, damage, effectHandleMode, SpellInfo::Effects, Player::GetBaseRune(), Player::GetCurrentRune(), Player::GetRuneCooldown(), Player::GetRunesState(), Object::GetTypeId(), SpellInfo::Id, Player::IsClass(), Unit::IsInCombat(), m_caster, m_runesState, m_spellInfo, MAX_RUNES, RUNE_DEATH, RUNE_FROST, Player::SetGracePeriod(), Player::SetRuneCooldown(), SPELL_EFFECT_HANDLE_LAUNCH, Object::ToPlayer(), and TYPEID_PLAYER.

◆ EffectActivateSpec()

void Spell::EffectActivateSpec ( SpellEffIndex  effIndex)
6138{
6140 return;
6141
6142 if (!unitTarget)
6143 return;
6144
6145 if (Player* player = unitTarget->ToPlayer())
6146 {
6147 player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1
6148 }
6149}

References damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectAddComboPoints()

void Spell::EffectAddComboPoints ( SpellEffIndex  effIndex)
4069{
4071 {
4072 return;
4073 }
4074
4075 if (!unitTarget || damage <= 0)
4076 {
4077 return;
4078 }
4079
4081}
void AddComboPointGain(Unit *target, int8 amount)
Definition: Spell.h:530

References AddComboPointGain(), damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectAddExtraAttacks()

void Spell::EffectAddExtraAttacks ( SpellEffIndex  effIndex)
4651{
4653 {
4654 return;
4655 }
4656
4657 if (!unitTarget || !unitTarget->IsAlive())
4658 {
4659 return;
4660 }
4661
4663
4665}
void AddExtraAttacks(uint32 count)
Definition: Unit.cpp:2729
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit *victim, uint32 attCount)
Definition: Spell.cpp:5102

References Unit::AddExtraAttacks(), damage, effectHandleMode, ExecuteLogEffectExtraAttacks(), Unit::IsAlive(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectAddFarsight()

void Spell::EffectAddFarsight ( SpellEffIndex  effIndex)
2696{
2698 return;
2699
2701 return;
2702
2703 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2704 int32 duration = m_spellInfo->GetDuration();
2705 // Caster not in world, might be spell triggered from aura removal
2706 if (!m_caster->IsInWorld())
2707 return;
2708
2709 // Remove old farsight if exist
2710 bool updateViewerVisibility = m_caster->RemoveDynObject(m_spellInfo->Id);
2711
2712 DynamicObject* dynObj = new DynamicObject(true);
2713 if (!dynObj->CreateDynamicObject(m_caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), m_caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS))
2714 {
2715 delete dynObj;
2716 return;
2717 }
2718
2719 dynObj->SetDuration(duration);
2720 dynObj->SetCasterViewpoint(updateViewerVisibility);
2721}
@ DYNAMIC_OBJECT_FARSIGHT_FOCUS
Definition: DynamicObject.h:31
void SetDuration(int32 newDuration)
Definition: DynamicObject.cpp:205
void SetCasterViewpoint(bool updateViewerVisibility)
Definition: DynamicObject.cpp:233
bool CreateDynamicObject(ObjectGuid::LowType guidlow, Unit *caster, uint32 spellId, Position const &pos, float radius, DynamicObjectType type)
Definition: DynamicObject.cpp:99
ObjectGuid::LowType GenerateLowGuid()
Definition: Map.h:638

References DynamicObject::CreateDynamicObject(), destTarget, DYNAMIC_OBJECT_FARSIGHT_FOCUS, effectHandleMode, SpellInfo::Effects, Map::GenerateLowGuid(), SpellInfo::GetDuration(), WorldObject::GetMap(), Object::GetTypeId(), SpellInfo::Id, Object::IsInWorld(), m_caster, m_spellInfo, Unit::RemoveDynObject(), DynamicObject::SetCasterViewpoint(), DynamicObject::SetDuration(), SPELL_EFFECT_HANDLE_HIT, and TYPEID_PLAYER.

◆ EffectAddHonor()

void Spell::EffectAddHonor ( SpellEffIndex  effIndex)
2766{
2768 return;
2769
2771 return;
2772
2773 // not scale value for item based reward (/10 value expected)
2774 if (m_CastItem)
2775 {
2776 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage / 10, false);
2777 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (item {}) for player: {}",
2779 return;
2780 }
2781
2782 // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
2783 if (damage <= 50)
2784 {
2786 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, honor_reward, false);
2787 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (scale) to player: {}",
2788 m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUID().ToString());
2789 }
2790 else
2791 {
2792 //maybe we have correct honor_gain in damage already
2793 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage, false);
2794 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (non scale) for player: {}",
2796 }
2797}
uint32 hk_honor_at_level(uint8 level, float multiplier=1.0f)
Definition: Formulas.h:38
std::string ToString() const
Definition: ObjectGuid.cpp:47
bool RewardHonor(Unit *victim, uint32 groupsize, int32 honor=-1, bool awardXP=true)
Definition: Player.cpp:6020

References damage, effectHandleMode, Object::GetEntry(), Object::GetGUID(), Unit::GetLevel(), Object::GetTypeId(), Acore::Honor::hk_honor_at_level(), SpellInfo::Id, LOG_DEBUG, m_CastItem, m_spellInfo, Player::RewardHonor(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), ObjectGuid::ToString(), TYPEID_PLAYER, and unitTarget.

◆ EffectApplyAreaAura()

void Spell::EffectApplyAreaAura ( SpellEffIndex  effIndex)
1308{
1310 return;
1311
1312 if (!m_spellAura || !unitTarget)
1313 return;
1316}
WorldObject * GetOwner() const
Definition: SpellAuras.h:107
void _ApplyEffectForTargets(uint8 effIndex)
Definition: SpellAuras.cpp:735

References Aura::_ApplyEffectForTargets(), ASSERT, effectHandleMode, Aura::GetOwner(), m_spellAura, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectApplyAura()

void Spell::EffectApplyAura ( SpellEffIndex  effIndex)

◆ EffectApplyGlyph()

void Spell::EffectApplyGlyph ( SpellEffIndex  effIndex)
4310{
4312 return;
4313
4315 return;
4316
4317 Player* player = m_caster->ToPlayer();
4318
4319 // glyph sockets level requirement
4320 uint8 minLevel = 0;
4321 switch (m_glyphIndex)
4322 {
4323 case 0:
4324 case 1:
4325 minLevel = 15;
4326 break;
4327 case 2:
4328 minLevel = 50;
4329 break;
4330 case 3:
4331 minLevel = 30;
4332 break;
4333 case 4:
4334 minLevel = 70;
4335 break;
4336 case 5:
4337 minLevel = 80;
4338 break;
4339 }
4340 if (minLevel && m_caster->GetLevel() < minLevel)
4341 {
4343 return;
4344 }
4345
4346 // apply new one
4347 if (uint32 glyph = m_spellInfo->Effects[effIndex].MiscValue)
4348 {
4349 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
4350 {
4351 if (GlyphSlotEntry const* glyphSlotEntry = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
4352 {
4353 if (glyphEntry->TypeFlags != glyphSlotEntry->TypeFlags)
4354 {
4356 return; // glyph slot mismatch
4357 }
4358 }
4359
4360 // remove old glyph aura
4361 if (uint32 oldGlyph = player->GetGlyph(m_glyphIndex))
4362 if (GlyphPropertiesEntry const* oldGlyphEntry = sGlyphPropertiesStore.LookupEntry(oldGlyph))
4363 {
4364 player->RemoveAurasDueToSpell(oldGlyphEntry->SpellId);
4365
4366 // Removed any triggered auras
4367 Unit::AuraMap& ownedAuras = player->GetOwnedAuras();
4368 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
4369 {
4370 Aura* aura = iter->second;
4371 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
4372 {
4373 if (triggeredByAuraSpellInfo->Id == oldGlyphEntry->SpellId)
4374 {
4375 player->RemoveOwnedAura(iter);
4376 continue;
4377 }
4378 }
4379 ++iter;
4380 }
4381
4382 player->SendLearnPacket(oldGlyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
4383 }
4384
4385 player->SendLearnPacket(glyphEntry->SpellId, true); // Send packet to properly handle client-side spell tooltips
4387 player->SetGlyph(m_glyphIndex, glyph, !player->GetSession()->PlayerLoading());
4388 player->SendTalentsInfoData(false);
4389 }
4390 }
4391}
DBCStorage< GlyphSlotEntry > sGlyphSlotStore(GlyphSlotfmt)
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
Definition: SpellDefines.h:148
#define MAX_GLYPH_SLOT_INDEX
Definition: SharedDefines.h:676
@ SPELL_FAILED_GLYPH_SOCKET_LOCKED
Definition: SharedDefines.h:1126
@ SPELL_FAILED_INVALID_GLYPH
Definition: SharedDefines.h:1124
void SendTalentsInfoData(bool pet)
Definition: Player.cpp:14368
void SendLearnPacket(uint32 spellId, bool learn)
Definition: Player.cpp:3018
uint32 GetGlyph(uint8 slot) const
Definition: Player.h:1746
uint32 GetGlyphSlot(uint8 slot) const
Definition: Player.h:1737
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition: Player.h:1738
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4661
std::multimap< uint32, Aura * > AuraMap
Definition: Unit.h:635
AuraMap & GetOwnedAuras()
Definition: Unit.h:1256
bool PlayerLoading() const
Definition: WorldSession.h:337
SpellInfo const * GetTriggeredByAuraSpellInfo() const
Definition: SpellAuras.cpp:2761
Definition: DBCStructure.h:1029

References Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, Player::GetGlyph(), Player::GetGlyphSlot(), Unit::GetLevel(), Unit::GetOwnedAuras(), Player::GetSession(), Aura::GetTriggeredByAuraSpellInfo(), Object::GetTypeId(), m_caster, m_glyphIndex, m_spellInfo, MAX_GLYPH_SLOT_INDEX, WorldSession::PlayerLoading(), Unit::RemoveAurasDueToSpell(), Unit::RemoveOwnedAura(), SendCastResult(), Player::SendLearnPacket(), Player::SendTalentsInfoData(), Player::SetGlyph(), sGlyphPropertiesStore, sGlyphSlotStore, SPELL_EFFECT_HANDLE_HIT, SPELL_FAILED_GLYPH_SOCKET_LOCKED, SPELL_FAILED_INVALID_GLYPH, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_IGNORE_CASTER_AURASTATE, TRIGGERED_IGNORE_SHAPESHIFT, and TYPEID_PLAYER.

◆ EffectBind()

void Spell::EffectBind ( SpellEffIndex  effIndex)
6271{
6273 return;
6274
6275 if (!unitTarget)
6276 return;
6277
6278 Player* player = unitTarget->ToPlayer();
6279 if (!player)
6280 {
6281 return;
6282 }
6283
6284 WorldLocation homeLoc;
6285 uint32 areaId = player->GetAreaId();
6286
6287 if (m_spellInfo->Effects[effIndex].MiscValue)
6288 areaId = m_spellInfo->Effects[effIndex].MiscValue;
6289
6290 if (m_targets.HasDst())
6291 homeLoc.WorldRelocate(*destTarget);
6292 else
6293 {
6294 homeLoc = player->GetWorldLocation();
6295 }
6296
6297 player->SetHomebind(homeLoc, areaId);
6298
6299 // binding
6300 WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4);
6301 data << float(homeLoc.GetPositionX());
6302 data << float(homeLoc.GetPositionY());
6303 data << float(homeLoc.GetPositionZ());
6304 data << uint32(homeLoc.GetMapId());
6305 data << uint32(areaId);
6306 player->SendDirectMessage(&data);
6307
6308 LOG_DEBUG("spells.aura", "EffectBind: New homebind X: {}, Y: {}, Z: {}, MapId: {}, AreaId: {}",
6309 homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
6310 // zone update
6311 data.Initialize(SMSG_PLAYERBOUND, 8 + 4);
6312 data << m_caster->GetGUID();
6313 data << uint32(areaId);
6314 player->SendDirectMessage(&data);
6315}
@ SMSG_BINDPOINTUPDATE
Definition: Opcodes.h:371
@ SMSG_PLAYERBOUND
Definition: Opcodes.h:374
Definition: Position.h:251
void WorldRelocate(const WorldLocation &loc)
Definition: Position.h:259
void GetWorldLocation(uint32 &mapId, float &x, float &y) const
Definition: Position.h:281
void SendDirectMessage(WorldPacket const *data) const
Definition: Player.cpp:5648
void SetHomebind(WorldLocation const &loc, uint32 areaId)
Definition: PlayerStorage.cpp:4911

References destTarget, effectHandleMode, SpellInfo::Effects, WorldObject::GetAreaId(), Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldLocation::GetWorldLocation(), SpellCastTargets::HasDst(), WorldPacket::Initialize(), LOG_DEBUG, m_caster, m_spellInfo, m_targets, Player::SendDirectMessage(), Player::SetHomebind(), SMSG_BINDPOINTUPDATE, SMSG_PLAYERBOUND, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), unitTarget, and WorldLocation::WorldRelocate().

◆ EffectBlock()

void Spell::EffectBlock ( SpellEffIndex  effIndex)
4677{
4679 return;
4680
4682 m_caster->ToPlayer()->SetCanBlock(true);
4683}
void SetCanBlock(bool value)
Definition: Player.cpp:13081

References effectHandleMode, Object::GetTypeId(), m_caster, Player::SetCanBlock(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), and TYPEID_PLAYER.

◆ EffectCastButtons()

void Spell::EffectCastButtons ( SpellEffIndex  effIndex)

Action button data is unverified when it's set so it can be "hacked" to contain invalid spells, so filter here.

6198{
6200 return;
6201
6203 return;
6204
6205 Player* p_caster = m_caster->ToPlayer();
6206 uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
6207 uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
6208
6209 for (; n_buttons; --n_buttons, ++button_id)
6210 {
6211 ActionButton const* ab = p_caster->GetActionButton(button_id);
6212 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
6213 continue;
6214
6217 uint32 spell_id = ab->GetAction();
6218 if (!spell_id)
6219 continue;
6220
6221 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
6222 if (!spellInfo)
6223 continue;
6224
6225 if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
6226 continue;
6227
6229 continue;
6230
6231 uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask(), this);
6232 if (m_caster->GetPower(POWER_MANA) < cost)
6233 continue;
6234
6236 m_caster->CastSpell(m_caster, spell_id, triggerFlags);
6237 }
6238}
@ ACTION_BUTTON_SPELL
Definition: Player.h:229
@ SPELL_ATTR7_CAN_BE_MULTI_CAST
Definition: SharedDefines.h:646
Definition: Player.h:253
uint32 GetAction() const
Definition: Player.h:261
ActionButtonType GetType() const
Definition: Player.h:260
ActionButton const * GetActionButton(uint8 button)
Definition: Player.cpp:5594
bool HasSpell(uint32 spell) const override
Definition: Player.cpp:3858

References ACTION_BUTTON_SPELL, SpellInfo::CalcPowerCost(), Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, ActionButton::GetAction(), Player::GetActionButton(), Unit::GetPower(), SpellInfo::GetSchoolMask(), ActionButton::GetType(), Object::GetTypeId(), SpellInfo::HasAttribute(), Player::HasSpell(), Player::HasSpellCooldown(), m_caster, m_spellInfo, POWER_MANA, SPELL_ATTR7_CAN_BE_MULTI_CAST, SPELL_EFFECT_HANDLE_HIT, sSpellMgr, Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, TRIGGERED_IGNORE_GCD, and TYPEID_PLAYER.

◆ EffectCharge()

void Spell::EffectCharge ( SpellEffIndex  effIndex)
4896{
4898 {
4899 if (!unitTarget)
4900 return;
4901
4902 ObjectGuid targetGUID = ObjectGuid::Empty;
4903 Player* player = m_caster->ToPlayer();
4904 if (player)
4905 {
4906 // charge changes fall time
4908
4910 {
4911 targetGUID = unitTarget->GetGUID();
4912 }
4913 }
4914
4915 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
4916 // Spell is not using explicit target - no generated path
4917 if (!m_preGeneratedPath)
4918 {
4920 m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed, EVENT_CHARGE, nullptr, false, 0.0f, targetGUID);
4921 }
4922 else
4923 {
4924 m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, targetGUID);
4925 }
4926
4927 if (player)
4928 {
4929 sScriptMgr->AnticheatSetUnderACKmount(player);
4930 }
4931 }
4932}
#define SPEED_CHARGE
Definition: MotionMaster.h:107
@ EVENT_CHARGE
Definition: SharedDefines.h:3311
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY)
Definition: Object.cpp:2818
Definition: Position.h:28
float m_positionZ
Definition: Position.h:58
float GetRelativeAngle(const Position *pos) const
Definition: Position.h:197
float m_positionX
Definition: Position.h:56
float m_positionY
Definition: Position.h:57
void SetFallInformation(uint32 time, float z)
Definition: Player.h:2312
MotionMaster * GetMotionMaster()
Definition: Unit.h:1604
void MoveCharge(float x, float y, float z, float speed=SPEED_CHARGE, uint32 id=EVENT_CHARGE, const Movement::PointsArray *path=nullptr, bool generatePath=false, float orientation=0.0f, ObjectGuid targetGUID=ObjectGuid::Empty)
Definition: MotionMaster.cpp:628

References effectHandleMode, ObjectGuid::Empty, EVENT_CHARGE, Unit::GetCombatReach(), WorldObject::GetFirstCollisionPosition(), GameTime::GetGameTime(), Object::GetGUID(), Unit::GetMotionMaster(), Position::GetPositionZ(), Position::GetRelativeAngle(), Unit::GetTarget(), SpellInfo::HasAttribute(), SpellInfo::IsPositive(), m_caster, Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_preGeneratedPath, m_spellInfo, MotionMaster::MoveCharge(), Player::SetFallInformation(), SpellInfo::Speed, SPEED_CHARGE, SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectChargeDest()

◆ EffectCreateItem()

void Spell::EffectCreateItem ( SpellEffIndex  effIndex)
1765{
1767 return;
1768
1769 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1770 ExecuteLogEffectCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1771}
void ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry)
Definition: Spell.cpp:5130
void DoCreateItem(uint8 effIndex, uint32 itemId)
Definition: SpellEffects.cpp:1635

References DoCreateItem(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectCreateItem(), m_spellInfo, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectCreateItem2()

void Spell::EffectCreateItem2 ( SpellEffIndex  effIndex)
Todo:
: ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
1774{
1776 return;
1777
1778 if (!unitTarget)
1779 return;
1780
1781 Player* player = unitTarget->ToPlayer();
1782 if (!player)
1783 {
1784 return;
1785 }
1786
1787 uint32 itemId = m_spellInfo->Effects[effIndex].ItemType;
1788
1789 if (itemId)
1790 DoCreateItem(effIndex, itemId);
1791
1792 // special case: fake item replaced by generate using spell_loot_template
1794 {
1795 if (itemId)
1796 {
1797 if (!player->HasItemCount(itemId))
1798 return;
1799
1800 // remove reagent
1801 uint32 count = 1;
1802 player->DestroyItemCount(itemId, count, true);
1803
1804 // create some random items
1806 }
1807 else
1808 player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); // create some random items
1809 }
1811}
LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false)
void AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const &store, bool broadcast=false)
Definition: Player.cpp:13436
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition: PlayerStorage.cpp:3136
bool IsLootCrafting() const
Definition: SpellInfo.cpp:924

References Player::AutoStoreLoot(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, Player::HasItemCount(), SpellInfo::Id, SpellInfo::IsLootCrafting(), LootTemplates_Spell, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectCreateRandomItem()

void Spell::EffectCreateRandomItem ( SpellEffIndex  effIndex)
Todo:
: ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
1814{
1816 return;
1817
1818 if (!unitTarget)
1819 return;
1820
1821 Player* player = unitTarget->ToPlayer();
1822 if (!player)
1823 {
1824 return;
1825 }
1826
1827 // create some random items
1830}

References Player::AutoStoreLoot(), effectHandleMode, SpellInfo::Id, LootTemplates_Spell, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectCreateTamedPet()

void Spell::EffectCreateTamedPet ( SpellEffIndex  effIndex)
5819{
5821 return;
5822
5824 return;
5825
5826 uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5827 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
5828 if (!pet)
5829 return;
5830
5831 // add to world
5832 pet->GetMap()->AddToMap(pet->ToCreature(), true);
5833
5834 // unitTarget has pet now
5835 unitTarget->SetMinion(pet, true);
5836
5837 pet->InitTalentForLevel();
5838
5840 {
5843 }
5844}
@ CLASS_HUNTER
Definition: SharedDefines.h:143
void InitTalentForLevel()
Definition: Pet.cpp:2225
void SavePetToDB(PetSaveMode mode)
Definition: Pet.cpp:507
void PetSpellInitialize()
Definition: Player.cpp:9424
void SetMinion(Minion *minion, bool apply)
Definition: Unit.cpp:10607
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition: Unit.cpp:17255
bool AddToMap(T *, bool checkTransport=false)
Definition: Map.cpp:555

References Map::AddToMap(), CLASS_CONTEXT_PET, CLASS_HUNTER, Unit::CreateTamedPetFrom(), effectHandleMode, SpellInfo::Effects, WorldObject::GetMap(), Unit::GetPetGUID(), Object::GetTypeId(), SpellInfo::Id, Pet::InitTalentForLevel(), Unit::IsClass(), m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), Unit::SetMinion(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectDestroyAllTotems()

void Spell::EffectDestroyAllTotems ( SpellEffIndex  effIndex)
5230{
5232 return;
5233
5234 int32 mana = 0;
5235 for (uint8 slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot)
5236 {
5237 if (!m_caster->m_SummonSlot[slot])
5238 continue;
5239
5241 if (totem && totem->IsTotem())
5242 {
5243 uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
5244 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
5245 if (spellInfo)
5246 {
5247 mana += spellInfo->ManaCost;
5249 }
5250 totem->ToTotem()->UnSummon();
5251 }
5252 }
5253 ApplyPct(mana, damage);
5254 if (mana)
5255 m_caster->CastCustomSpell(m_caster, 39104, &mana, nullptr, nullptr, true);
5256}
T ApplyPct(T &base, U pct)
Definition: Util.h:73
@ UNIT_CREATED_BY_SPELL
Definition: UpdateFields.h:138
#define SUMMON_SLOT_TOTEM
Definition: Unit.h:597
#define MAX_TOTEM_SLOT
Definition: Unit.h:598
void UnSummon(uint32 msTime=0) override
Definition: Totem.cpp:122
Totem * ToTotem()
Definition: Unit.h:1741
SpellCastResult CastCustomSpell(Unit *victim, uint32 spellId, int32 const *bp0, int32 const *bp1, int32 const *bp2, bool triggered, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition: Unit.cpp:1208
uint32 GetCreateMana() const
Definition: Unit.h:1383
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition: Unit.h:1410
Creature * GetCreature(ObjectGuid const guid)
Definition: Map.cpp:3314
uint32 ManaCostPercentage
Definition: SpellInfo.h:367
uint32 ManaCost
Definition: SpellInfo.h:363

References ApplyPct(), CalculatePct(), Unit::CastCustomSpell(), damage, effectHandleMode, Unit::GetCreateMana(), Map::GetCreature(), WorldObject::GetMap(), Object::GetUInt32Value(), Unit::IsTotem(), m_caster, Unit::m_SummonSlot, SpellInfo::ManaCost, SpellInfo::ManaCostPercentage, MAX_TOTEM_SLOT, SPELL_EFFECT_HANDLE_HIT, sSpellMgr, SUMMON_SLOT_TOTEM, Unit::ToTotem(), UNIT_CREATED_BY_SPELL, and Totem::UnSummon().

◆ EffectDiscoverTaxi()

void Spell::EffectDiscoverTaxi ( SpellEffIndex  effIndex)
5847{
5849 return;
5850
5851 if (!unitTarget)
5852 return;
5853
5854 Player* player = unitTarget->ToPlayer();
5855 if (!player)
5856 {
5857 return;
5858 }
5859
5860 uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue;
5861 if (sTaxiNodesStore.LookupEntry(nodeid))
5862 player->GetSession()->SendDiscoverNewTaxiNode(nodeid);
5863}
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
void SendDiscoverNewTaxiNode(uint32 nodeid)
Definition: TaxiHandler.cpp:152

References effectHandleMode, SpellInfo::Effects, Player::GetSession(), m_spellInfo, WorldSession::SendDiscoverNewTaxiNode(), SPELL_EFFECT_HANDLE_HIT_TARGET, sTaxiNodesStore, Object::ToPlayer(), and unitTarget.

◆ EffectDisEnchant()

void Spell::EffectDisEnchant ( SpellEffIndex  effIndex)
4447{
4449 return;
4450
4452 return;
4453
4454 if (Player* caster = m_caster->ToPlayer())
4455 {
4456 caster->UpdateCraftSkill(m_spellInfo->Id);
4457 caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
4458 }
4459
4460 // item will be removed at disenchanting end
4461}
@ LOOT_DISENCHANTING
Definition: LootMgr.h:84

References ItemTemplate::DisenchantID, effectHandleMode, Object::GetGUID(), Item::GetTemplate(), SpellInfo::Id, itemTarget, LOOT_DISENCHANTING, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and Object::ToPlayer().

◆ EffectDismissPet()

void Spell::EffectDismissPet ( SpellEffIndex  effIndex)
4533{
4535 return;
4536
4537 if (!unitTarget || !unitTarget->IsPet())
4538 return;
4539
4540 Pet* pet = unitTarget->ToPet();
4541
4542 ExecuteLogEffectUnsummonObject(effIndex, pet);
4544}
@ PET_SAVE_NOT_IN_SLOT
Definition: PetDefines.h:45
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition: Pet.cpp:884
void ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject *obj)
Definition: Spell.cpp:5148

References effectHandleMode, ExecuteLogEffectUnsummonObject(), Unit::IsPet(), PET_SAVE_NOT_IN_SLOT, Pet::Remove(), SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), and unitTarget.

◆ EffectDispel()

void Spell::EffectDispel ( SpellEffIndex  effIndex)
2545{
2547 return;
2548
2549 if (!unitTarget)
2550 return;
2551
2552 // Create dispel mask by dispel type
2553 uint32 dispel_type = m_spellInfo->Effects[effIndex].MiscValue;
2554 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(dispel_type));
2555
2556 DispelChargesList dispel_list;
2557 unitTarget->GetDispellableAuraList(m_caster, dispelMask, dispel_list, m_spellInfo);
2558 if (dispel_list.empty())
2559 return;
2560
2561 // Ok if exist some buffs for dispel try dispel it
2562 uint32 failCount = 0;
2563 DispelChargesList success_list;
2564 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
2565 // dispel N = damage buffs (or while exist buffs for dispel)
2566 for (int32 count = 0; count < damage && !dispel_list.empty();)
2567 {
2568 // Random select buff for dispel
2569 DispelChargesList::iterator itr = dispel_list.begin();
2570 std::advance(itr, urand(0, dispel_list.size() - 1));
2571
2572 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
2573 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
2574 if (!chance)
2575 {
2576 dispel_list.erase(itr);
2577 continue;
2578 }
2579 else
2580 {
2581 if (roll_chance_i(chance))
2582 {
2583 bool alreadyListed = false;
2584 for (DispelChargesList::iterator successItr = success_list.begin(); successItr != success_list.end(); ++successItr)
2585 {
2586 if (successItr->first->GetId() == itr->first->GetId())
2587 {
2588 ++successItr->second;
2589 alreadyListed = true;
2590 }
2591 }
2592 if (!alreadyListed)
2593 success_list.push_back(std::make_pair(itr->first, 1));
2594 --itr->second;
2595 if (itr->second <= 0)
2596 dispel_list.erase(itr);
2597 }
2598 else
2599 {
2600 if (!failCount)
2601 {
2602 // Failed to dispell
2603 dataFail << m_caster->GetGUID(); // Caster GUID
2604 dataFail << unitTarget->GetGUID(); // Victim GUID
2605 dataFail << uint32(m_spellInfo->Id); // dispel spell id
2606 }
2607 ++failCount;
2608 dataFail << uint32(itr->first->GetId()); // Spell Id
2609 }
2610 ++count;
2611 }
2612 }
2613
2614 if (failCount)
2615 m_caster->SendMessageToSet(&dataFail, true);
2616
2617 // put in combat
2620
2621 if (success_list.empty())
2622 return;
2623
2624 WorldPacket dataSuccess(SMSG_SPELLDISPELLOG, 8 + 8 + 4 + 1 + 4 + success_list.size() * 5);
2625 // Send packet header
2626 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
2627 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
2628 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
2629 dataSuccess << uint8(0); // not used
2630 dataSuccess << uint32(success_list.size()); // count
2631 for (DispelChargesList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
2632 {
2633 // Send dispelled spell info
2634 dataSuccess << uint32(itr->first->GetId()); // Spell Id
2635 dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed
2636 unitTarget->RemoveAurasDueToSpellByDispel(itr->first->GetId(), m_spellInfo->Id, itr->first->GetCasterGUID(), m_caster, itr->second);
2637 }
2638 m_caster->SendMessageToSet(&dataSuccess, true);
2639
2640 // On success dispel
2641 // Devour Magic
2643 {
2644 int32 heal_amount = m_spellInfo->Effects[EFFECT_1].CalcValue();
2645 m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, nullptr, nullptr, true);
2646 // Glyph of Felhunter
2647 if (Unit* owner = m_caster->GetOwner())
2648 if (owner->GetAura(56249))
2649 owner->CastCustomSpell(owner, 19658, &heal_amount, nullptr, nullptr, true);
2650 }
2651}
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:44
@ SPELLCATEGORY_DEVOUR_MAGIC
Definition: SpellMgr.h:40
@ SPELLFAMILY_WARLOCK
Definition: SharedDefines.h:3533
@ SMSG_DISPEL_FAILED
Definition: Opcodes.h:640
@ SMSG_SPELLDISPELLOG
Definition: Opcodes.h:665
void GetDispellableAuraList(Unit *caster, uint32 dispelMask, DispelChargesList &dispelList, SpellInfo const *dispelSpell)
Definition: Unit.cpp:5550
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, Unit *dispeller, uint8 chargesRemoved=1)
Definition: Unit.cpp:4898
uint32 GetCategory() const
Definition: SpellInfo.cpp:870

References Unit::CastCustomSpell(), damage, EFFECT_1, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), Unit::GetDispellableAuraList(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetOwner(), Object::GetPackGUID(), SpellInfo::Id, Unit::IsFriendlyTo(), m_caster, m_spellInfo, Unit::RemoveAurasDueToSpellByDispel(), roll_chance_i(), WorldObject::SendMessageToSet(), SMSG_DISPEL_FAILED, SMSG_SPELLDISPELLOG, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLCATEGORY_DEVOUR_MAGIC, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyName, HostileRefMgr::threatAssist(), unitTarget, and urand().

◆ EffectDispelMechanic()

void Spell::EffectDispelMechanic ( SpellEffIndex  effIndex)
5135{
5137 return;
5138
5139 if (!unitTarget)
5140 return;
5141
5142 uint32 mechanic = m_spellInfo->Effects[effIndex].MiscValue;
5143
5144 std::queue<std::pair<uint32, ObjectGuid>> dispel_list;
5145
5146 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5147 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5148 {
5149 Aura* aura = itr->second;
5151 continue;
5153 {
5154 if ((aura->GetSpellInfo()->GetAllEffectsMechanicMask() & (1 << mechanic)))
5155 {
5156 dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID()));
5157
5158 // spell only removes 1 bleed effect do not continue
5159 if (m_spellInfo->Effects[effIndex].BasePoints == 1)
5160 {
5161 break;
5162 }
5163 }
5164 }
5165 }
5166
5167 for (; dispel_list.size(); dispel_list.pop())
5168 {
5169 unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
5170 }
5171
5172 // put in combat
5175}
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition: SpellAuraDefines.h:394
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4732
ObjectGuid GetCasterGUID() const
Definition: SpellAuras.h:105
uint32 GetId() const
Definition: SpellAuras.cpp:466
int32 CalcDispelChance(Unit *auraTarget, bool offensive) const
Definition: SpellAuras.cpp:1182

References AURA_REMOVE_BY_ENEMY_SPELL, Aura::CalcDispelChance(), effectHandleMode, SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Aura::GetApplicationOfTarget(), Aura::GetCasterGUID(), Object::GetGUID(), Unit::getHostileRefMgr(), Aura::GetId(), Unit::GetOwnedAuras(), Aura::GetSpellInfo(), Unit::IsFriendlyTo(), m_caster, m_spellInfo, Unit::RemoveAura(), roll_chance_i(), SPELL_EFFECT_HANDLE_HIT_TARGET, HostileRefMgr::threatAssist(), and unitTarget.

◆ EffectDistract()

void Spell::EffectDistract ( SpellEffIndex  effIndex)

@BUG Causes the player to stop moving + interrupts spellcast.

2668{
2670 return;
2671
2672 // Check for possible target
2673 if (!unitTarget || unitTarget->IsEngaged())
2674 return;
2675
2676 // target must be OK to do this
2678 return;
2679
2682}
@ UNIT_STATE_CONFUSED
Definition: UnitDefines.h:160
@ UNIT_STATE_FLEEING
Definition: UnitDefines.h:156
@ UNIT_STATE_STUNNED
Definition: UnitDefines.h:152
float GetAngle(const Position *pos) const
Definition: Position.cpp:77
void SetFacingTo(float ori)
Definition: Unit.cpp:20417
bool IsEngaged() const
Definition: Unit.h:1028
void MoveDistract(uint32 time)
Definition: MotionMaster.cpp:748

References damage, destTarget, effectHandleMode, Position::GetAngle(), Unit::GetMotionMaster(), Unit::HasUnitState(), IN_MILLISECONDS, Unit::IsEngaged(), MotionMaster::MoveDistract(), Unit::SetFacingTo(), SPELL_EFFECT_HANDLE_HIT_TARGET, UNIT_STATE_CONFUSED, UNIT_STATE_FLEEING, UNIT_STATE_STUNNED, and unitTarget.

◆ EffectDualWield()

void Spell::EffectDualWield ( SpellEffIndex  effIndex)
2654{
2656 return;
2657
2659}
virtual void SetCanDualWield(bool value)
Definition: Unit.h:686

References effectHandleMode, Unit::SetCanDualWield(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectDuel()

void Spell::EffectDuel ( SpellEffIndex  effIndex)
4084{
4086 return;
4087
4089 return;
4090
4091 Player* caster = m_caster->ToPlayer();
4092 Player* target = unitTarget->ToPlayer();
4093
4094 // caster or target already have requested duel
4095 if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID()))
4096 return;
4097
4098 // Players can only fight a duel in zones with this flag
4099 AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId());
4100 if (casterAreaEntry && !(casterAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4101 {
4102 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4103 return;
4104 }
4105
4106 AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId());
4107 if (targetAreaEntry && !(targetAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4108 {
4109 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4110 return;
4111 }
4112
4113 //CREATE DUEL FLAG OBJECT
4114 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
4115 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
4116
4117 Map* map = m_caster->GetMap();
4118 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id,
4119 map, m_caster->GetPhaseMask(),
4123 m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4124 {
4125 delete pGameObj;
4126 return;
4127 }
4128
4131 int32 duration = m_spellInfo->GetDuration();
4132 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4133 pGameObj->SetSpellId(m_spellInfo->Id);
4134
4135 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4136
4137 m_caster->AddGameObject(pGameObj);
4138 map->AddToMap(pGameObj, true);
4139 //END
4140
4141 // Send request
4142 WorldPacket data(SMSG_DUEL_REQUESTED, 8 + 8);
4143 data << pGameObj->GetGUID();
4144 data << caster->GetGUID();
4145 caster->GetSession()->SendPacket(&data);
4146 target->GetSession()->SendPacket(&data);
4147
4148 // create duel-info
4149 bool isMounted = (GetSpellInfo()->Id == 62875);
4150 caster->duel = std::make_unique<DuelInfo>(target, caster, isMounted);
4151 target->duel = std::make_unique<DuelInfo>(caster, caster, isMounted);
4152
4153 caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4154 target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4155
4156 sScriptMgr->OnPlayerDuelRequest(target, caster);
4157}
@ PLAYER_DUEL_ARBITER
Definition: UpdateFields.h:177
@ GAMEOBJECT_LEVEL
Definition: UpdateFields.h:403
@ GAMEOBJECT_FACTION
Definition: UpdateFields.h:402
@ AREA_FLAG_ALLOW_DUELS
Definition: DBCEnums.h:240
@ SPELL_FAILED_NO_DUELING
Definition: SharedDefines.h:1028
@ SMSG_DUEL_REQUESTED
Definition: Opcodes.h:389
virtual bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const &rotation, uint32 animprogress, GOState go_state, uint32 artKit=0)
Definition: GameObject.cpp:254
void SetRespawnTime(int32 respawn)
Definition: GameObject.cpp:1303
void SetSpellId(uint32 id)
Definition: GameObject.h:177
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:650
uint32 GetPhaseMask() const
Definition: Object.h:437
float GetOrientation() const
Definition: Position.h:120
PlayerSocial * GetSocial()
Definition: Player.h:1140
bool HasIgnore(ObjectGuid ignore_guid) const
Definition: SocialMgr.cpp:193
Definition: Transport.h:112
uint32 GetFaction() const
Definition: Unit.h:839
void AddGameObject(GameObject *gameObj)
Definition: Unit.cpp:6124
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
Definition: WorldSession.cpp:214
void ExecuteLogEffectSummonObject(uint8 effIndex, WorldObject *obj)
Definition: Spell.cpp:5142
uint32 flags
Definition: DBCStructure.h:524

References Unit::AddGameObject(), Map::AddToMap(), AREA_FLAG_ALLOW_DUELS, GameObject::Create(), Player::duel, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), AreaTableEntry::flags, GAMEOBJECT_FACTION, GAMEOBJECT_LEVEL, Map::GenerateLowGuid(), WorldObject::GetAreaId(), SpellInfo::GetDuration(), Unit::GetFaction(), Object::GetGUID(), Unit::GetLevel(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::GetSession(), Player::GetSocial(), GetSpellInfo(), Object::GetTypeId(), GO_STATE_READY, PlayerSocial::HasIgnore(), SpellInfo::Id, IN_MILLISECONDS, m_caster, m_spellInfo, PLAYER_DUEL_ARBITER, sAreaTableStore, SendCastResult(), WorldSession::SendPacket(), Object::SetGuidValue(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), Object::SetUInt32Value(), SMSG_DUEL_REQUESTED, sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_NO_DUELING, sScriptMgr, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectDummy()

void Spell::EffectDummy ( SpellEffIndex  effIndex)
667{
669 return;
670
672 return;
673
674 // selection by spell family
676 {
678 {
679 switch (m_spellInfo->Id)
680 {
681 // Trial of the Champion, Trample
682 case 67866:
683 {
685 unitTarget->CastSpell(unitTarget, 67867, false);
686 return;
687 }
688 // Trial of the Champion, Hammer of the Righteous
689 case 66867:
690 {
691 if( !unitTarget )
692 return;
693 if( unitTarget->HasAura(66940) )
694 m_caster->CastSpell(unitTarget, 66903, true);
695 else
696 m_caster->CastSpell(unitTarget, 66904, true);
697 return;
698 }
699 case 17731:
700 case 69294:
701 {
703 return;
704
708 trigger->CastSpell(trigger, 17731, false);
709
710 return;
711 }
712 // HoL, Arc Weld
713 case 59086:
714 {
716 m_caster->CastSpell(m_caster, 59097, true);
717
718 return;
719 }
720 }
721 break;
722 }
724 switch (m_spellInfo->Id)
725 {
726 case 31789: // Righteous Defense (step 1)
727 {
728 if (!unitTarget)
729 return;
730 // not empty (checked), copy
732
733 // remove invalid attackers
734 for (Unit::AttackerSet::iterator aItr = attackers.begin(); aItr != attackers.end();)
735 if (!(*aItr)->IsValidAttackTarget(m_caster))
736 aItr = attackers.erase(aItr);
737 else
738 ++aItr;
739
740 // selected from list 3
741 uint32 maxTargets = std::min<uint32>(3, attackers.size());
742 for (uint32 i = 0; i < maxTargets; ++i)
743 {
744 Unit::AttackerSet::iterator aItr = attackers.begin();
745 std::advance(aItr, urand(0, attackers.size() - 1));
746 m_caster->CastSpell((*aItr), 31790, true);
747 attackers.erase(aItr);
748 }
749
750 return;
751 }
752 }
753 break;
755 // Hunger for Blood
756 if( m_spellInfo->Id == 51662 )
757 {
758 m_caster->CastSpell(m_caster, 63848, true);
759 return;
760 }
761 break;
762 }
763
764 // pet auras
765 if (PetAura const* petSpell = sSpellMgr->GetPetAura(m_spellInfo->Id, effIndex))
766 {
767 m_caster->AddPetAura(petSpell);
768 return;
769 }
770
771 // normal DB scripted effect
772 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectDummy({})", m_spellInfo->Id, effIndex);
774
775 if (gameObjTarget)
776 {
777 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, gameObjTarget);
778 }
779 else if (unitTarget && unitTarget->GetTypeId() == TYPEID_UNIT)
780 {
781 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, unitTarget->ToCreature());
782 }
783 else if (itemTarget)
784 {
785 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, itemTarget);
786 }
787}
@ TEMPSUMMON_TIMED_DESPAWN
Definition: Object.h:47
@ UNIT_FIELD_MOUNTDISPLAYID
Definition: UpdateFields.h:126
ScriptMapMap sSpellScripts
Definition: ObjectMgr.cpp:57
@ SPELLFAMILY_GENERIC
Definition: SharedDefines.h:3528
@ SPELLFAMILY_PALADIN
Definition: SharedDefines.h:3538
@ SPELLFAMILY_ROGUE
Definition: SharedDefines.h:3536
uint8 GetGoAnimProgress() const
Definition: GameObject.h:210
time_t GetRespawnTime() const
Definition: GameObject.h:184
TempSummon * SummonCreature(uint32 id, const Position &pos, TempSummonType spwtype=TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime=0, uint32 vehId=0, SummonPropertiesEntry const *properties=nullptr, bool visibleBySummonerOnly=false) const
Definition: Object.cpp:2352
void AddPetAura(PetAura const *petSpell)
Definition: Unit.cpp:17201
std::unordered_set< Unit * > AttackerSet
Definition: Unit.h:632
AttackerSet const & getAttackers() const
Definition: Unit.h:723
void ScriptsStart(std::map< uint32, std::multimap< uint32, ScriptInfo > > const &scripts, uint32 id, Object *source, Object *target)
Put scripts in the execution queue.
Definition: MapScripts.cpp:33
Definition: SpellMgr.h:470

References Unit::AddPetAura(), Unit::CastSpell(), effectHandleMode, gameObjTarget, Unit::getAttackers(), GameTime::GetGameTime(), GameObject::GetGoAnimProgress(), WorldObject::GetMap(), GameObject::GetRespawnTime(), Object::GetTypeId(), Object::GetUInt32Value(), Unit::HasAura(), SpellInfo::Id, Unit::isMoving(), Unit::IsVehicle(), itemTarget, LOG_DEBUG, m_caster, m_spellInfo, Map::ScriptsStart(), GameObject::SendCustomAnim(), GameObject::SetRespawnTime(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SpellInfo::SpellFamilyName, sScriptMgr, sSpellMgr, sSpellScripts, WorldObject::SummonCreature(), TEMPSUMMON_TIMED_DESPAWN, Object::ToCreature(), Object::ToPlayer(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_FIELD_MOUNTDISPLAYID, unitTarget, and urand().

◆ EffectDurabilityDamage()

void Spell::EffectDurabilityDamage ( SpellEffIndex  effIndex)
5259{
5261 return;
5262
5263 if (!unitTarget)
5264 return;
5265
5266 Player* player = unitTarget->ToPlayer();
5267 if (!player)
5268 {
5269 return;
5270 }
5271
5272 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5273
5274 // -1 means all player equipped items and -2 all items
5275 if (slot < 0)
5276 {
5277 player->DurabilityPointsLossAll(damage, (slot < -1));
5279 return;
5280 }
5281
5282 // invalid slot value
5283 if (slot >= INVENTORY_SLOT_BAG_END)
5284 return;
5285
5286 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5287 {
5288 player->DurabilityPointsLoss(item, damage);
5289 ExecuteLogEffectDurabilityDamage(effIndex, unitTarget, item->GetEntry(), slot);
5290 }
5291}
@ INVENTORY_SLOT_BAG_END
Definition: Player.h:700
#define INVENTORY_SLOT_BAG_0
Definition: Player.h:670
Item * GetItemByPos(uint16 pos) const
Definition: PlayerStorage.cpp:464
void DurabilityPointsLossAll(int32 points, bool inventory)
Definition: Player.cpp:4702
void DurabilityPointsLoss(Item *item, int32 points)
Definition: Player.cpp:4728
void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
Definition: Spell.cpp:5116

References damage, Player::DurabilityPointsLoss(), Player::DurabilityPointsLossAll(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectDurabilityDamage(), Object::GetEntry(), Player::GetItemByPos(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectDurabilityDamagePCT()

void Spell::EffectDurabilityDamagePCT ( SpellEffIndex  effIndex)
5294{
5296 return;
5297
5298 if (!unitTarget)
5299 return;
5300
5301 Player* player = unitTarget->ToPlayer();
5302 if (!player)
5303 {
5304 return;
5305 }
5306
5307 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5308
5309 // FIXME: some spells effects have value -1/-2
5310 // Possibly its mean -1 all player equipped items and -2 all items
5311 if (slot < 0)
5312 {
5313 player->DurabilityLossAll(float(damage) / 100.0f, (slot < -1));
5314 return;
5315 }
5316
5317 // invalid slot value
5318 if (slot >= INVENTORY_SLOT_BAG_END)
5319 return;
5320
5321 if (damage <= 0)
5322 return;
5323
5324 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5325 player->DurabilityLoss(item, float(damage) / 100.0f);
5326}
void DurabilityLossAll(double percent, bool inventory)
Definition: Player.cpp:4658
void DurabilityLoss(Item *item, double percent)
Definition: Player.cpp:4684

References damage, Player::DurabilityLoss(), Player::DurabilityLossAll(), effectHandleMode, SpellInfo::Effects, Player::GetItemByPos(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectEnchantHeldItem()

void Spell::EffectEnchantHeldItem ( SpellEffIndex  effIndex)
4394{
4396 return;
4397
4398 // this is only item spell effect applied to main-hand weapon of target player (players in area)
4399 if (!unitTarget)
4400 return;
4401
4402 Player* item_owner = unitTarget->ToPlayer();
4403 if (!item_owner)
4404 {
4405 return;
4406 }
4407
4409 if (!item)
4410 return;
4411
4412 // must be equipped
4413 if (!item->IsEquipped())
4414 return;
4415
4416 if (m_spellInfo->Effects[effIndex].MiscValue)
4417 {
4418 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
4419 int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
4420 if (!duration)
4421 duration = damage * IN_MILLISECONDS; //+1; //Base points after ..
4422 if (!duration)
4423 duration = 10 * IN_MILLISECONDS; //10 seconds for enchants which don't have listed duration
4424
4425 // Xinef: Venomhide poison, no other spell uses this effect...
4426 if (m_spellInfo->Id == 14792)
4427 duration = 5 * MINUTE * IN_MILLISECONDS;
4428
4429 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
4430 if (!pEnchant)
4431 return;
4432
4433 // Always go to temp enchantment slot
4435
4436 // Enchantment will not be applied if a different one already exists
4437 if (item->GetEnchantmentId(slot) && item->GetEnchantmentId(slot) != enchant_id)
4438 return;
4439
4440 // Apply the temporary enchantment
4441 item->SetEnchantment(slot, enchant_id, duration, pEnchant->charges, m_caster->GetGUID());
4442 item_owner->ApplyEnchantment(item, slot, true);
4443 }
4444}
EnchantmentSlot
Definition: Item.h:168
@ TEMP_ENCHANTMENT_SLOT
Definition: Item.h:170
@ EQUIPMENT_SLOT_MAINHAND
Definition: Player.h:690
bool IsEquipped() const
Definition: Item.cpp:790
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster=ObjectGuid::Empty)
Definition: Item.cpp:921
void ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool apply_dur=true, bool ignore_condition=false)
Definition: PlayerStorage.cpp:4319
uint32 charges
Definition: DBCStructure.h:1843

References Player::ApplyEnchantment(), SpellItemEnchantmentEntry::charges, damage, effectHandleMode, SpellInfo::Effects, EQUIPMENT_SLOT_MAINHAND, SpellInfo::GetDuration(), Item::GetEnchantmentId(), Object::GetGUID(), Player::GetItemByPos(), SpellInfo::Id, IN_MILLISECONDS, INVENTORY_SLOT_BAG_0, Item::IsEquipped(), m_caster, m_spellInfo, MINUTE, Item::SetEnchantment(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and unitTarget.

◆ EffectEnchantItemPerm()

void Spell::EffectEnchantItemPerm ( SpellEffIndex  effIndex)
2812{
2814 return;
2815
2817 return;
2818 if (!itemTarget)
2819 return;
2820
2821 Player* p_caster = m_caster->ToPlayer();
2822
2823 // Handle vellums
2825 {
2826 // destroy one vellum from stack
2827 uint32 count = 1;
2828 p_caster->DestroyItemCount(itemTarget, count, true);
2829 unitTarget = p_caster;
2830 // and add a scroll
2831 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
2832 itemTarget = nullptr;
2833 m_targets.SetItemTarget(nullptr);
2834 }
2835 else
2836 {
2837 // do not increase skill if vellum used
2839 p_caster->UpdateCraftSkill(m_spellInfo->Id);
2840
2841 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2842 if (!enchant_id)
2843 return;
2844
2845 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2846 if (!pEnchant)
2847 return;
2848
2849 // item can be in trade slot and have owner diff. from caster
2850 Player* item_owner = itemTarget->GetOwner();
2851 if (!item_owner)
2852 return;
2853
2854 // remove old enchanting before applying new if equipped
2856
2858
2859 // add new enchanting if equipped
2861
2862 item_owner->RemoveTradeableItem(itemTarget);
2864 }
2865}
@ PERM_ENCHANTMENT_SLOT
Definition: Item.h:169
void ClearSoulboundTradeable(Player *currentOwner)
Definition: Item.cpp:1265
void RemoveTradeableItem(Item *item)
Definition: PlayerStorage.cpp:4154
void SetItemTarget(Item *item)
Definition: Spell.cpp:328

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, ItemTemplate::Flags, Object::GetGUID(), Item::GetOwner(), Item::GetTemplate(), Object::GetTypeId(), SpellInfo::Id, Item::IsArmorVellum(), Item::IsWeaponVellum(), ITEM_FLAG_NO_REAGENT_COST, itemTarget, m_caster, m_CastItem, m_spellInfo, m_targets, PERM_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, Object::ToPlayer(), TYPEID_PLAYER, unitTarget, and Player::UpdateCraftSkill().

◆ EffectEnchantItemPrismatic()

void Spell::EffectEnchantItemPrismatic ( SpellEffIndex  effIndex)
2868{
2870 return;
2871
2873 return;
2874 if (!itemTarget)
2875 return;
2876
2877 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2878 if (!enchant_id)
2879 return;
2880
2881 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2882 if (!pEnchant)
2883 return;
2884
2885 // support only enchantings with add socket in this slot
2886 {
2887 bool add_socket = false;
2888 for (uint8 i = 0; i < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++i)
2889 {
2890 if (pEnchant->type[i] == ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET)
2891 {
2892 add_socket = true;
2893 break;
2894 }
2895 }
2896 if (!add_socket)
2897 {
2898 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemPrismatic: attempt apply enchant spell {} with SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC ({}) but without ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET ({}), not suppoted yet.",
2900 return;
2901 }
2902 }
2903
2904 // item can be in trade slot and have owner diff. from caster
2905 Player* item_owner = itemTarget->GetOwner();
2906 if (!item_owner)
2907 return;
2908
2909 // remove old enchanting before applying new if equipped
2911
2913
2914 // add new enchanting if equipped
2916
2917 item_owner->RemoveTradeableItem(itemTarget);
2919}

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Object::GetTypeId(), SpellInfo::Id, ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET, itemTarget, LOG_ERROR, m_caster, m_spellInfo, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, PRISMATIC_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Item::SetEnchantment(), SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, SpellItemEnchantmentEntry::type, and TYPEID_PLAYER.

◆ EffectEnchantItemTmp()

void Spell::EffectEnchantItemTmp ( SpellEffIndex  effIndex)
2922{
2924 return;
2925
2927 return;
2928
2929 Player* p_caster = m_caster->ToPlayer();
2930
2931 // Rockbiter Weapon apply to both weapon
2932 if (!itemTarget)
2933 return;
2935 {
2936 uint32 spell_id = 0;
2937
2938 // enchanting spell selected by calculated damage-per-sec stored in Effect[1] base value
2939 // Note: damage calculated (correctly) with rounding int32(float(v)) but
2940 // RW enchantments applied damage int32(float(v)+0.5), this create 0..1 difference sometime
2941 switch (damage)
2942 {
2943 // Rank 1
2944 case 2:
2945 spell_id = 36744;
2946 break; // 0% [ 7% == 2, 14% == 2, 20% == 2]
2947 // Rank 2
2948 case 4:
2949 spell_id = 36753;
2950 break; // 0% [ 7% == 4, 14% == 4]
2951 case 5:
2952 spell_id = 36751;
2953 break; // 20%
2954 // Rank 3
2955 case 6:
2956 spell_id = 36754;
2957 break; // 0% [ 7% == 6, 14% == 6]
2958 case 7:
2959 spell_id = 36755;
2960 break; // 20%
2961 // Rank 4
2962 case 9:
2963 spell_id = 36761;
2964 break; // 0% [ 7% == 6]
2965 case 10:
2966 spell_id = 36758;
2967 break; // 14%
2968 case 11:
2969 spell_id = 36760;
2970 break; // 20%
2971 default:
2972 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: Damage {} not handled in S'RW", damage);
2973 return;
2974 }
2975
2976 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
2977 if (!spellInfo)
2978 {
2979 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: unknown spell id {}", spell_id);
2980 return;
2981 }
2982
2983 for (int j = BASE_ATTACK; j <= OFF_ATTACK; ++j)
2984 {
2985 if (Item* item = p_caster->GetWeaponForAttack(WeaponAttackType(j)))
2986 {
2987 if (item->IsFitToSpellRequirements(m_spellInfo))
2988 {
2989 Spell* spell = new Spell(m_caster, spellInfo, TRIGGERED_FULL_MASK);
2990 SpellCastTargets targets;
2991 targets.SetItemTarget(item);
2992 spell->prepare(&targets);
2993 }
2994 }
2995 }
2996 return;
2997 }
2998 if (!itemTarget)
2999 return;
3000
3001 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
3002
3003 if (!enchant_id)
3004 {
3005 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have 0 as enchanting id", m_spellInfo->Id, effIndex);
3006 return;
3007 }
3008
3009 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
3010 if (!pEnchant)
3011 {
3012 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have not existed enchanting id {} ", m_spellInfo->Id, effIndex, enchant_id);
3013 return;
3014 }
3015
3016 // select enchantment duration
3017 uint32 duration;
3018
3019 // rogue family enchantments exception by duration
3020 if (m_spellInfo->Id == 38615)
3021 duration = 1800; // 30 mins
3022 // other rogue family enchantments always 1 hour (some have spell damage=0, but some have wrong data in EffBasePoints)
3024 duration = 3600; // 1 hour
3025 // shaman family enchantments
3027 duration = 1800; // 30 mins
3028 // other cases with this SpellVisual already selected
3029 else if (m_spellInfo->SpellVisual[0] == 215)
3030 duration = 1800; // 30 mins
3031 // some fishing pole bonuses except Glow Worm which lasts full hour
3032 else if (m_spellInfo->SpellVisual[0] == 563 && m_spellInfo->Id != 64401)
3033 duration = 600; // 10 mins
3034 // shaman rockbiter enchantments
3035 else if (m_spellInfo->SpellVisual[0] == 0)
3036 duration = 1800; // 30 mins
3037 else if (m_spellInfo->Id == 29702)
3038 duration = 300; // 5 mins
3039 else if (m_spellInfo->Id == 37360)
3040 duration = 300; // 5 mins
3041 // default case
3042 else
3043 duration = 3600; // 1 hour
3044
3045 // item can be in trade slot and have owner diff. from caster
3046 Player* item_owner = itemTarget->GetOwner();
3047 if (!item_owner)
3048 return;
3049
3050 // remove old enchanting before applying new if equipped
3052
3053 itemTarget->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, duration * 1000, pEnchant->charges, m_caster->GetGUID());
3054
3055 // add new enchanting if equipped
3057
3058 item_owner->RemoveTradeableItem(itemTarget);
3060}
WeaponAttackType
Definition: Unit.h:208
@ SPELLFAMILY_SHAMAN
Definition: SharedDefines.h:3539
Definition: Spell.h:109
SpellCastResult prepare(SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
Definition: Spell.cpp:3467
std::array< uint32, 2 > SpellVisual
Definition: SpellInfo.h:379

References Player::ApplyEnchantment(), BASE_ATTACK, SpellItemEnchantmentEntry::charges, Item::ClearSoulboundTradeable(), damage, effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Object::GetTypeId(), Player::GetWeaponForAttack(), SpellInfo::Id, itemTarget, LOG_ERROR, m_caster, m_spellInfo, OFF_ATTACK, prepare(), Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellVisual, sSpellItemEnchantmentStore, sSpellMgr, TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), TRIGGERED_FULL_MASK, and TYPEID_PLAYER.

◆ EffectEnergize()

void Spell::EffectEnergize ( SpellEffIndex  effIndex)
1867{
1869 return;
1870
1871 if (!unitTarget)
1872 return;
1873 if (!unitTarget->IsAlive())
1874 return;
1875
1876 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1877 return;
1878
1879 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1880
1883 return;
1884
1885 if (unitTarget->GetMaxPower(power) == 0)
1886 return;
1887
1888 // Some level depends spells
1889 int level_multiplier = 0;
1890 int level_diff = 0;
1891 switch (m_spellInfo->Id)
1892 {
1893 case 9512: // Restore Energy
1894 level_diff = m_caster->GetLevel() - 40;
1895 level_multiplier = 2;
1896 break;
1897 case 24571: // Blood Fury
1898 level_diff = m_caster->GetLevel() - 60;
1899 level_multiplier = 10;
1900 break;
1901 case 24532: // Burst of Energy
1902 level_diff = m_caster->GetLevel() - 60;
1903 level_multiplier = 4;
1904 break;
1905 case 31930: // Judgements of the Wise
1906 case 63375: // Improved Stormstrike
1907 case 68082: // Glyph of Seal of Command
1909 break;
1910 case 48542: // Revitalize
1912 break;
1913 case 71132: // Glyph of Shadow Word: Pain
1914 damage = int32(CalculatePct(unitTarget->GetCreateMana(), 1)); // set 1 as value, missing in dbc
1915 break;
1916 default:
1917 break;
1918 }
1919
1920 if (level_diff > 0)
1921 damage -= level_multiplier * level_diff;
1922
1923 if (damage < 0)
1924 return;
1925
1927
1928 // Mad Alchemist's Potion
1929 if (m_spellInfo->Id == 45051)
1930 {
1931 // find elixirs on target
1932 bool guardianFound = false;
1933 bool battleFound = false;
1935 for (Unit::AuraApplicationMap::iterator itr = Auras.begin(); itr != Auras.end(); ++itr)
1936 {
1937 SpellGroupSpecialFlags sFlag = sSpellMgr->GetSpellGroupSpecialFlags(itr->second->GetBase()->GetId());
1938 if (!guardianFound)
1940 guardianFound = true;
1941 if (!battleFound)
1943 battleFound = true;
1944 if (battleFound && guardianFound)
1945 break;
1946 }
1947
1948 // get all available elixirs by mask and spell level
1949 std::set<uint32> availableElixirs;
1950 if (!guardianFound)
1951 sSpellMgr->GetSetOfSpellsInSpellGroupWithFlag(1, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN, availableElixirs);
1952 if (!battleFound)
1953 sSpellMgr->GetSetOfSpellsInSpellGroupWithFlag(1, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE, availableElixirs);
1954 for (std::set<uint32>::iterator itr = availableElixirs.begin(); itr != availableElixirs.end();)
1955 {
1956 SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(*itr);
1957 if (spellInfo->SpellLevel < m_spellInfo->SpellLevel || spellInfo->SpellLevel > unitTarget->GetLevel())
1958 availableElixirs.erase(itr++);
1959 else
1960 ++itr;
1961 }
1962
1963 if (!availableElixirs.empty())
1964 {
1965 // cast random elixir on target
1967 }
1968 }
1969}
SpellGroupSpecialFlags
Definition: SpellMgr.h:334
@ SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE
Definition: SpellMgr.h:336
@ SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN
Definition: SpellMgr.h:337
@ SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED
Definition: SharedDefines.h:657
@ SPELLFAMILY_POTION
Definition: SharedDefines.h:3541
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:133
void EnergizeBySpell(Unit *victim, uint32 SpellID, uint32 Damage, Powers powertype)
Definition: Unit.cpp:11193

References CalculatePct(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetAppliedAuras(), Unit::GetCreateMana(), Unit::GetLevel(), Unit::GetMaxPower(), Object::GetTypeId(), Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_CastItem, m_spellInfo, MAX_POWERS, Acore::Containers::SelectRandomContainerElement(), SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN, SPELLFAMILY_POTION, SpellInfo::SpellFamilyName, SpellInfo::SpellLevel, sSpellMgr, TYPEID_PLAYER, and unitTarget.

◆ EffectEnergizePct()

void Spell::EffectEnergizePct ( SpellEffIndex  effIndex)
1972{
1974 return;
1975
1976 if (!unitTarget)
1977 return;
1978 if (!unitTarget->IsAlive())
1979 return;
1980
1981 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1982 return;
1983
1984 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1985
1987 return;
1988
1989 uint32 maxPower = unitTarget->GetMaxPower(power);
1990 if (maxPower == 0)
1991 return;
1992
1993 uint32 gain = CalculatePct(maxPower, damage);
1995}

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetMaxPower(), Object::GetTypeId(), Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_spellInfo, MAX_POWERS, SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED, SPELL_EFFECT_HANDLE_HIT_TARGET, TYPEID_PLAYER, and unitTarget.

◆ EffectEnvironmentalDMG()

void Spell::EffectEnvironmentalDMG ( SpellEffIndex  effIndex)
303{
305 return;
306
307 if (!unitTarget || !unitTarget->IsAlive())
308 return;
309
310 if (unitTarget->IsPlayer())
312 else
313 {
315
316 uint32 absorb = dmgInfo.GetAbsorb();
317 uint32 resist = dmgInfo.GetResist();
318 uint32 envDamage = dmgInfo.GetDamage();
319
320 Unit::DealDamageMods(unitTarget, envDamage, &absorb);
321 damage = envDamage;
322
324 }
325}
@ DAMAGE_FIRE
Definition: Player.h:839
uint32 EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
Definition: Player.cpp:753

References damage, DAMAGE_FIRE, Unit::DealDamageMods(), effectHandleMode, Player::EnvironmentalDamage(), DamageInfo::GetAbsorb(), DamageInfo::GetDamage(), DamageInfo::GetResist(), SpellInfo::GetSchoolMask(), Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, Unit::SendSpellNonMeleeDamageLog(), SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectFeedPet()

void Spell::EffectFeedPet ( SpellEffIndex  effIndex)
Todo:
: fix crash when a spell has two effects, both pointed at the same item target
4500{
4502 return;
4503
4504 Player* player = m_caster->ToPlayer();
4505 if (!player)
4506 return;
4507
4508 Item* foodItem = itemTarget;
4509 if (!foodItem)
4510 return;
4511
4512 Pet* pet = player->GetPet();
4513 if (!pet)
4514 return;
4515
4516 if (!pet->IsAlive())
4517 return;
4518
4519 int32 benefit = pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel);
4520 if (benefit <= 0)
4521 return;
4522
4523 ExecuteLogEffectDestroyItem(effIndex, foodItem->GetEntry());
4524
4525 uint32 count = 1;
4526 player->DestroyItemCount(foodItem, count, true);
4528
4529 m_caster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, nullptr, nullptr, true);
4530}
void ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry)
Definition: Spell.cpp:5136

References Unit::CastCustomSpell(), Player::DestroyItemCount(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectDestroyItem(), Pet::GetCurrentFoodBenefitLevel(), Object::GetEntry(), Player::GetPet(), Item::GetTemplate(), Unit::IsAlive(), ItemTemplate::ItemLevel, itemTarget, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and Object::ToPlayer().

◆ EffectForceCast()

void Spell::EffectForceCast ( SpellEffIndex  effIndex)
1001{
1003 return;
1004
1005 if (!unitTarget)
1006 return;
1007
1008 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1009
1010 // normal case
1011 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1012
1013 if (!spellInfo)
1014 {
1015 LOG_ERROR("spells.effect", "Spell::EffectForceCast of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1016 return;
1017 }
1018
1019 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST && damage)
1020 {
1021 switch (m_spellInfo->Id)
1022 {
1023 case 52588: // Skeletal Gryphon Escape
1024 case 48598: // Ride Flamebringer Cue
1026 break;
1027 case 52463: // Hide In Mine Car
1028 case 52349: // Overtake
1029 unitTarget->CastCustomSpell(unitTarget, spellInfo->Id, &damage, nullptr, nullptr, true, nullptr, nullptr, m_originalCasterGUID);
1030 return;
1031 case 72378: // Blood Nova
1032 case 73058: // Blood Nova
1033 m_caster->CastSpell(unitTarget, damage, true); // additional spell cast
1034 break;
1035 }
1036 }
1037
1038 CustomSpellValues values;
1039 // set basepoints for trigger with value effect
1041 {
1042 // maybe need to set value only when basepoints == 0?
1046 }
1047
1048 SpellCastTargets targets;
1049 targets.SetUnitTarget(m_caster);
1050
1051 unitTarget->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK);
1052}
@ SPELLVALUE_BASE_POINT1
Definition: SpellDefines.h:115
@ SPELLVALUE_BASE_POINT2
Definition: SpellDefines.h:116
@ SPELLVALUE_BASE_POINT0
Definition: SpellDefines.h:114
@ SPELL_EFFECT_FORCE_CAST
Definition: SharedDefines.h:918
@ SPELL_EFFECT_FORCE_CAST_WITH_VALUE
Definition: SharedDefines.h:919
Definition: SpellDefines.h:163
void AddSpellMod(SpellValueMod mod, int32 value)
Definition: SpellDefines.h:165

References CustomSpellValues::AddSpellMod(), Unit::CastCustomSpell(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, SpellInfo::Id, LOG_ERROR, m_caster, m_originalCasterGUID, m_spellInfo, Unit::RemoveAura(), SpellCastTargets::SetUnitTarget(), SPELL_EFFECT_FORCE_CAST, SPELL_EFFECT_FORCE_CAST_WITH_VALUE, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, TRIGGERED_FULL_MASK, and unitTarget.

◆ EffectForceDeselect()

void Spell::EffectForceDeselect ( SpellEffIndex  effIndex)
4756{
4758 return;
4759
4760 // xinef: clear focus
4762
4764 data << m_caster->GetGUID();
4765
4767 Acore::MessageDistDelivererToHostile notifier(m_caster, &data, dist);
4768 Cell::VisitWorldObjects(m_caster, notifier, dist);
4769
4770 // xinef: we should also force pets to remove us from current target
4771 Unit::AttackerSet attackerSet;
4772 for (Unit::AttackerSet::const_iterator itr = m_caster->getAttackers().begin(); itr != m_caster->getAttackers().end(); ++itr)
4773 if ((*itr)->GetTypeId() == TYPEID_UNIT && !(*itr)->CanHaveThreatList())
4774 attackerSet.insert(*itr);
4775
4776 for (Unit::AttackerSet::const_iterator itr = attackerSet.begin(); itr != attackerSet.end(); ++itr)
4777 (*itr)->AttackStop();
4778
4779 // Xinef: Mirror images code Initialize Images
4780 if (m_spellInfo->Id == 58836)
4781 {
4782 std::vector<Unit*> images;
4783 for (Unit::ControlSet::const_iterator itr = m_caster->m_Controlled.begin(); itr != m_caster->m_Controlled.end(); ++itr)
4784 if ((*itr)->GetEntry() == 31216 /*NPC_MIRROR_IMAGE*/)
4785 images.push_back(*itr);
4786
4787 if (images.empty())
4788 return;
4789
4790 UnitList targets;
4791 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, m_caster->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4794 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4795 {
4796 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4797 continue;
4798
4799 if (Spell* spell = (*iter)->GetCurrentSpell(CURRENT_GENERIC_SPELL))
4800 {
4801 if (spell->m_targets.GetUnitTargetGUID() == m_caster->GetGUID())
4802 {
4803 SpellInfo const* si = spell->GetSpellInfo();
4804 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->GetTypeId() == TYPEID_UNIT)
4805 {
4806 Creature* c = (*iter)->ToCreature();
4807 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4808 continue;
4809 }
4810
4811 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4812 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4813 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4814 {
4815 // at least one effect truly targets an unit, interrupt the spell
4816 interrupt = true;
4817 break;
4818 }
4819
4820 if (interrupt)
4821 spell->m_targets.SetUnitTarget(images.at(urand(0, images.size() - 1)));
4822 }
4823 }
4824 }
4825 }
4826}
#define VISIBILITY_COMPENSATION
Definition: ObjectDefines.h:26
std::list< Unit * > UnitList
Definition: Unit.h:76
@ TARGET_OBJECT_TYPE_UNIT
Definition: SpellInfo.h:101
@ TARGET_OBJECT_TYPE_UNIT_AND_DEST
Definition: SpellInfo.h:102
@ CREATURE_ELITE_WORLDBOSS
Definition: SharedDefines.h:2734
@ SPELL_ATTR6_IGNORE_PHASE_SHIFT
Definition: SharedDefines.h:617
@ SMSG_CLEAR_TARGET
Definition: Opcodes.h:989
bool IsDungeonBoss() const
Definition: Creature.cpp:3131
uint32 rank
Definition: CreatureData.h:209
ControlSet m_Controlled
Definition: Unit.h:1209
void SendClearTarget()
Definition: Unit.cpp:20216
static void VisitAllObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:207
static void VisitWorldObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:193
Definition: GridNotifiers.h:133
Definition: GridNotifiers.h:423
Definition: GridNotifiers.h:861

References CREATURE_ELITE_WORLDBOSS, CURRENT_GENERIC_SPELL, effectHandleMode, SpellInfo::Effects, Unit::getAttackers(), Creature::GetCreatureTemplate(), Object::GetGUID(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), SpellInfo::Id, Creature::IsDungeonBoss(), Unit::IsPet(), Creature::isWorldBoss(), m_caster, Unit::m_Controlled, m_spellInfo, MAX_SPELL_EFFECTS, CreatureTemplate::rank, Unit::SendClearTarget(), SMSG_CLEAR_TARGET, SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_EFFECT_HANDLE_HIT, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), TYPEID_UNIT, UNIT_STATE_CASTING, urand(), VISIBILITY_COMPENSATION, Cell::VisitAllObjects(), and Cell::VisitWorldObjects().

◆ EffectGameObjectDamage()

void Spell::EffectGameObjectDamage ( SpellEffIndex  effIndex)
5891{
5893 return;
5894
5895 if (!gameObjTarget)
5896 return;
5897
5898 Unit* caster = m_originalCaster;
5899 if (!caster)
5900 return;
5901
5902 FactionTemplateEntry const* casterFaction = caster->GetFactionTemplateEntry();
5904 // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
5905 if ((casterFaction && targetFaction && !casterFaction->IsFriendlyTo(*targetFaction)) || !targetFaction)
5907}
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
void ModifyHealth(int32 change, Unit *attackerOrHealer=nullptr, uint32 spellId=0)
Definition: GameObject.cpp:2268
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition: Unit.cpp:9970
Definition: DBCStructure.h:939
bool IsFriendlyTo(FactionTemplateEntry const &entry) const
Definition: DBCStructure.h:951

References damage, effectHandleMode, GAMEOBJECT_FACTION, gameObjTarget, Unit::GetFactionTemplateEntry(), GetSpellInfo(), Object::GetUInt32Value(), FactionTemplateEntry::IsFriendlyTo(), m_originalCaster, GameObject::ModifyHealth(), sFactionTemplateStore, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectGameObjectRepair()

void Spell::EffectGameObjectRepair ( SpellEffIndex  effIndex)

◆ EffectGameObjectSetDestructionState()

void Spell::EffectGameObjectSetDestructionState ( SpellEffIndex  effIndex)
5921{
5923 return;
5924
5926 return;
5927
5930}
GameObjectDestructibleState
Definition: SharedDefines.h:1626
void SetDestructibleState(GameObjectDestructibleState state, Player *eventInvoker=nullptr, bool setHealth=false)
Definition: GameObject.cpp:2331

References effectHandleMode, SpellInfo::Effects, gameObjTarget, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), m_originalCaster, m_spellInfo, GameObject::SetDestructibleState(), and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectHeal()

void Spell::EffectHeal ( SpellEffIndex  effIndex)
1461{
1463 return;
1464
1465 if (unitTarget && unitTarget->IsAlive() && damage >= 0)
1466 {
1467 // Try to get original caster
1469
1470 // Skip if m_originalCaster not available
1471 if (!caster)
1472 return;
1473
1474 int32 addhealth = damage;
1475
1476 // Vessel of the Naaru (Vial of the Sunwell trinket)
1477 if (m_spellInfo->Id == 45064)
1478 {
1479 // Amount of heal - depends from stacked Holy Energy
1480 int damageAmount = 0;
1481 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(45062, 0))
1482 {
1483 damageAmount += aurEff->GetAmount();
1485 }
1486
1487 addhealth += damageAmount;
1488 }
1489 // Swiftmend - consumes Regrowth or Rejuvenation
1491 {
1493 // find most short by duration
1494 AuraEffect* forcedTargetAura = nullptr;
1495 AuraEffect* targetAura = nullptr;
1496 for (Unit::AuraEffectList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
1497 {
1498 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID
1499 && (*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x50)
1500 {
1501 if (m_caster->GetGUID() == (*i)->GetCasterGUID())
1502 {
1503 if (!forcedTargetAura || (*i)->GetBase()->GetDuration() < forcedTargetAura->GetBase()->GetDuration())
1504 forcedTargetAura = *i;
1505 }
1506 else if (!targetAura || (*i)->GetBase()->GetDuration() < targetAura->GetBase()->GetDuration())
1507 targetAura = *i;
1508 }
1509 }
1510
1511 if (forcedTargetAura)
1512 targetAura = forcedTargetAura;
1513
1514 if (!targetAura)
1515 {
1516 LOG_ERROR("spells.effect", "Target({}) has aurastate AURA_STATE_SWIFTMEND but no matching aura.", unitTarget->GetGUID().ToString());
1517 return;
1518 }
1519
1520 int32 tickheal = targetAura->GetAmount();
1521 if (Unit* auraCaster = targetAura->GetCaster())
1522 tickheal = unitTarget->SpellHealingBonusTaken(auraCaster, targetAura->GetSpellInfo(), tickheal, DOT);
1523
1524 //int32 tickheal = targetAura->GetSpellInfo()->EffectBasePoints[idx] + 1;
1525 //It is said that talent bonus should not be included
1526
1527 int32 tickcount = 0;
1528 // Rejuvenation
1529 if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x10)
1530 tickcount = 4;
1531 // Regrowth
1532 else // if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x40)
1533 tickcount = 6;
1534
1535 addhealth += tickheal * tickcount;
1536
1537 // Glyph of Swiftmend
1538 if (!caster->HasAura(54824))
1539 unitTarget->RemoveAura(targetAura->GetId(), targetAura->GetCasterGUID());
1540
1541 //addhealth += tickheal * tickcount;
1542 //addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth, HEAL, unitTarget);
1543 }
1544 // Death Pact - return pct of max health to caster
1546 {
1547 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL, effIndex);
1548 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1549 }
1550 else if (m_spellInfo->Id != 33778) // not lifebloom
1551 {
1552 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effIndex);
1553 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1554 }
1555
1556 // Implemented this way as there is no other way to do it currently (that I know :P)...
1557 if (caster->ToPlayer() && caster->HasAura(23401)) // Nefarian Corrupted Healing (priest)
1558 {
1560 {
1561 m_damage = 0;
1562 caster->CastSpell(unitTarget, 23402, false); // Nefarian Corrupted Healing Periodic Damage effect.
1563 return;
1564 }
1565 }
1566
1567 m_damage -= addhealth;
1568 }
1569}
@ DOT
Definition: Unit.h:250
@ SPELL_AURA_PERIODIC_HEAL
Definition: SpellAuraDefines.h:71
@ SPELLFAMILY_DRUID
Definition: SharedDefines.h:3535
@ SPELLFAMILY_DEATHKNIGHT
Definition: SharedDefines.h:3543
@ AURA_STATE_SWIFTMEND
Definition: SharedDefines.h:1307
@ SPELL_SCHOOL_MASK_HOLY
Definition: SharedDefines.h:298
uint32 CountPctFromMaxHealth(int32 pct) const
Definition: Unit.h:790
SpellInfo const * GetSpellInfo() const
Definition: SpellAuraEffects.h:54
uint32 GetId() const
Definition: SpellAuraEffects.cpp:432
Unit * GetCaster() const
Definition: SpellAuraEffects.h:47
Aura * GetBase() const
Definition: SpellAuraEffects.h:49
ObjectGuid GetCasterGUID() const
Definition: SpellAuraEffects.h:48
int32 GetAmount() const
Definition: SpellAuraEffects.h:64
uint32 TargetAuraState
Definition: SpellInfo.h:340

References AURA_STATE_SWIFTMEND, Unit::CastSpell(), Unit::CountPctFromMaxHealth(), damage, DOT, effectHandleMode, AuraEffect::GetAmount(), Unit::GetAuraEffect(), Unit::GetAuraEffectsByType(), AuraEffect::GetBase(), AuraEffect::GetCaster(), AuraEffect::GetCasterGUID(), Aura::GetDuration(), Object::GetGUID(), AuraEffect::GetId(), SpellInfo::GetSchoolMask(), AuraEffect::GetSpellInfo(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), HEAL, SpellInfo::Id, Unit::IsAlive(), LOG_ERROR, m_caster, m_damage, m_originalCaster, m_originalCasterGUID, m_spellInfo, Unit::RemoveAura(), Unit::RemoveAurasDueToSpell(), SPELL_AURA_PERIODIC_HEAL, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_SCHOOL_MASK_HOLY, SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_DRUID, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Unit::SpellHealingBonusDone(), Unit::SpellHealingBonusTaken(), SpellInfo::TargetAuraState, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectHealMaxHealth()

void Spell::EffectHealMaxHealth ( SpellEffIndex  effIndex)
3663{
3665 return;
3666
3667 if (!unitTarget || !unitTarget->IsAlive())
3668 return;
3669
3670 int32 addhealth = 0;
3671
3672 // damage == 0 - heal for caster max health
3673 if (damage == 0)
3674 addhealth = m_caster->GetMaxHealth();
3675 else
3676 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
3677
3678 m_healing += addhealth;
3679}
uint32 GetMaxHealth() const
Definition: Unit.h:782

References damage, effectHandleMode, Unit::GetHealth(), Unit::GetMaxHealth(), Unit::IsAlive(), m_caster, m_healing, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectHealMechanical()

void Spell::EffectHealMechanical ( SpellEffIndex  effIndex)

◆ EffectHealPct()

void Spell::EffectHealPct ( SpellEffIndex  effIndex)

◆ EffectHealthLeech()

void Spell::EffectHealthLeech ( SpellEffIndex  effIndex)
1607{
1609 return;
1610
1611 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
1612 return;
1613
1616
1617 LOG_DEBUG("spells.aura", "HealthLeech :{}", damage);
1618
1619 // xinef: handled in spell.cpp
1620 //float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1621
1622 m_damage += damage;
1623 // get max possible damage, don't count overkill for heal
1624 //uint32 healthGain = uint32(-unitTarget->GetHealthGain(-damage) * healMultiplier);
1625
1626 //if (m_caster->IsAlive())
1627 //{
1628 // healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL);
1629 // healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
1630
1631 // m_caster->HealBySpell(m_caster, m_spellInfo, uint32(healthGain));
1632 //}
1633}
uint32 SpellDamageBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack=1)
Definition: Unit.cpp:11713
uint32 SpellDamageBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition: Unit.cpp:11537

References damage, effectHandleMode, Unit::IsAlive(), LOG_DEBUG, m_caster, m_damage, m_spellInfo, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), and unitTarget.

◆ EffectInebriate()

void Spell::EffectInebriate ( SpellEffIndex  effIndex)
4464{
4466 return;
4467
4468 if (!unitTarget)
4469 return;
4470
4471 Player* player = unitTarget->ToPlayer();
4472 if (!player)
4473 {
4474 return;
4475 }
4476
4477 uint8 currentDrunk = player->GetDrunkValue();
4478 int32 drunkMod = damage;
4479
4480 if (drunkMod == 0)
4481 return;
4482
4483 // drunkMod may contain values ​​that are guaranteed to cause uint8 overflow/underflow (examples: 29690, 46874)
4484 // In addition, we would not want currentDrunk to become more than 100.
4485 // So before adding the values, let's check that everything is fine.
4486 if (drunkMod > 0 && drunkMod > static_cast<int32>(100 - currentDrunk))
4487 currentDrunk = 100;
4488 else if (drunkMod < 0 && drunkMod < static_cast<int32>(0 - currentDrunk))
4489 currentDrunk = 0;
4490 else
4491 currentDrunk += drunkMod; // Due to previous checks we can be sure that currentDrunk will not go beyond [0-100] range.
4492
4493 player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0);
4494
4495 if (currentDrunk == 100 && roll_chance_i(25))
4496 player->CastSpell(player, 67468, false); // Drunken Vomit
4497}
uint8 GetDrunkValue() const
Definition: Player.h:2147
void SetDrunkValue(uint8 newDrunkValue, uint32 itemId=0)
Definition: Player.cpp:970

References Unit::CastSpell(), damage, effectHandleMode, Player::GetDrunkValue(), Object::GetEntry(), m_CastItem, roll_chance_i(), Player::SetDrunkValue(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectInstaKill()

void Spell::EffectInstaKill ( SpellEffIndex  effIndex)
279{
281 return;
282
283 if (!unitTarget || !unitTarget->IsAlive() || unitTarget->HasAura(27827)) // Spirit of redemption doesn't make you death, but can cause infinite loops
284 return;
285
288 return;
289
290 if (m_caster == unitTarget) // prevent interrupt message
291 finish();
292
293 WorldPacket data(SMSG_SPELLINSTAKILLLOG, 8 + 8 + 4);
294 data << m_caster->GetGUID();
295 data << unitTarget->GetGUID();
296 data << uint32(m_spellInfo->Id);
297 m_caster->SendMessageToSet(&data, true);
298
300}
@ CHEAT_GOD
Definition: Player.h:998
@ SPELL_SCHOOL_MASK_NORMAL
Definition: SharedDefines.h:297
@ SMSG_SPELLINSTAKILLLOG
Definition: Opcodes.h:845
static uint32 DealDamage(Unit *attacker, Unit *victim, uint32 damage, CleanDamage const *cleanDamage=nullptr, DamageEffectType damagetype=DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *spellProto=nullptr, bool durabilityLoss=true, bool allowGM=false, Spell const *spell=nullptr)
Definition: Unit.cpp:797

References CHEAT_GOD, Unit::DealDamage(), effectHandleMode, finish(), Player::GetCommandStatus(), Object::GetGUID(), Unit::GetHealth(), Object::GetTypeId(), Unit::HasAura(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_spellInfo, NODAMAGE, WorldObject::SendMessageToSet(), SMSG_SPELLINSTAKILLLOG, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_SCHOOL_MASK_NORMAL, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectInterruptCast()

void Spell::EffectInterruptCast ( SpellEffIndex  effIndex)
Todo:
: not all spells that used this effect apply cooldown at school spells
3682{
3684 return;
3685
3686 if (!unitTarget || !unitTarget->IsAlive())
3687 return;
3688
3690 // also exist case: apply cooldown to interrupted cast only and to all spells
3691 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3693 {
3695 {
3696 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3697 // check if we can interrupt spell
3698 if ((spell->getState() == SPELL_STATE_CASTING
3699 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3703 {
3704 if (m_originalCaster)
3705 {
3707 unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), duration/*spellInfo->GetDuration()*/);
3708 }
3709 ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
3711 }
3712 }
3713 }
3714}
#define CURRENT_FIRST_NON_MELEE_SPELL
Definition: Unit.h:543
CurrentSpellTypes
Definition: Unit.h:536
@ CURRENT_CHANNELED_SPELL
Definition: Unit.h:539
@ CURRENT_AUTOREPEAT_SPELL
Definition: Unit.h:540
@ CHANNEL_INTERRUPT_FLAG_INTERRUPT
Definition: SpellDefines.h:38
@ SPELL_INTERRUPT_FLAG_INTERRUPT
Definition: SpellDefines.h:30
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:4021
int32 CalcSpellDuration(SpellInfo const *spellProto)
Definition: Unit.cpp:14770
virtual void ProhibitSpellSchool(SpellSchoolMask, uint32)
Definition: Unit.h:1390
void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit *victim, uint32 spellId)
Definition: Spell.cpp:5109
uint32 ChannelInterruptFlags
Definition: SpellInfo.h:354
uint32 InterruptFlags
Definition: SpellInfo.h:352

References Unit::CalcSpellDuration(), CHANNEL_INTERRUPT_FLAG_INTERRUPT, SpellInfo::ChannelInterruptFlags, CURRENT_AUTOREPEAT_SPELL, CURRENT_CHANNELED_SPELL, CURRENT_FIRST_NON_MELEE_SPELL, CURRENT_GENERIC_SPELL, effectHandleMode, ExecuteLogEffectInterruptCast(), Unit::GetCurrentSpell(), SpellInfo::GetSchoolMask(), SpellInfo::Id, SpellInfo::InterruptFlags, Unit::InterruptSpell(), Unit::IsAlive(), m_originalCaster, m_spellInfo, Unit::ModSpellDuration(), SpellInfo::PreventionType, Unit::ProhibitSpellSchool(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_INTERRUPT_FLAG_INTERRUPT, SPELL_PREVENTION_TYPE_SILENCE, SPELL_STATE_CASTING, SPELL_STATE_PREPARING, and unitTarget.

◆ EffectJump()

void Spell::EffectJump ( SpellEffIndex  effIndex)
1074{
1076 return;
1077
1078 if (m_caster->IsInFlight())
1079 return;
1080
1081 if (!unitTarget)
1082 return;
1083
1084 float speedXY, speedZ;
1085 CalculateJumpSpeeds(effIndex, m_caster->GetExactDist2d(unitTarget), speedXY, speedZ);
1086 m_caster->GetMotionMaster()->MoveJump(*unitTarget, speedXY, speedZ);
1087
1089 {
1090 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1091 }
1092}
float GetExactDist2d(const float x, const float y) const
Definition: Position.h:166
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=0)
Definition: MotionMaster.h:227
void CalculateJumpSpeeds(uint8 i, float dist, float &speedxy, float &speedz)
Definition: SpellEffects.cpp:1157

References CalculateJumpSpeeds(), effectHandleMode, Position::GetExactDist2d(), Unit::GetMotionMaster(), Object::GetTypeId(), Unit::IsInFlight(), m_caster, MotionMaster::MoveJump(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, sScriptMgr, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectJumpDest()

void Spell::EffectJumpDest ( SpellEffIndex  effIndex)
1095{
1097 return;
1098
1099 if (m_caster->IsInFlight())
1100 return;
1101
1102 if (!m_targets.HasDst() || m_caster->GetVehicle())
1103 return;
1104
1105 // Init dest coordinates
1106 float x, y, z;
1107 destTarget->GetPosition(x, y, z);
1108 // xinef: this can happen if MovePositionToFirstCollision detects that X, Y cords are invalid and returns prematurely
1109 if (!Acore::IsValidMapCoord(x, y, z) || z <= INVALID_HEIGHT)
1110 return;
1111
1112 float speedXY, speedZ;
1113 float dist = m_caster->GetExactDist2d(x, y);
1114 CalculateJumpSpeeds(effIndex, dist, speedXY, speedZ);
1115
1116 // Override, calculations are incorrect
1117 if (m_spellInfo->Id == 49376) // feral charge
1118 {
1119 speedXY = pow(speedZ * 10, 8);
1121
1122 if (Player* player = m_caster->ToPlayer())
1123 {
1124 player->SetCanTeleport(true);
1125 }
1126
1128 {
1129 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1130 }
1131
1132 return;
1133 }
1134
1135 if (m_spellInfo->Id == 57604) // death grip
1136 {
1137 speedZ = 3.0f;
1138 speedXY = 50.0f;
1139 }
1140
1141 // crash fix?
1142 if (speedXY < 1.0f)
1143 speedXY = 1.0f;
1144
1145 if (Player* player = m_caster->ToPlayer())
1146 {
1147 player->SetCanTeleport(true);
1148 }
1149 m_caster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ);
1150
1152 {
1153 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1154 }
1155}
@ UNIT_FIELD_TARGET
Definition: UpdateFields.h:92
#define INVALID_HEIGHT
Definition: Map.h:165
bool IsValidMapCoord(float c)
Definition: GridDefines.h:216
ObjectGuid GetGuidValue(uint16 index) const
Definition: Object.cpp:337

References CalculateJumpSpeeds(), destTarget, effectHandleMode, Position::GetExactDist2d(), Object::GetGuidValue(), Unit::GetMotionMaster(), Position::GetPosition(), Object::GetTypeId(), ObjectAccessor::GetUnit(), Unit::GetVehicle(), SpellCastTargets::HasDst(), SpellInfo::Id, INVALID_HEIGHT, Unit::IsInFlight(), Acore::IsValidMapCoord(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), SPELL_EFFECT_HANDLE_LAUNCH, sScriptMgr, Object::ToPlayer(), TYPEID_PLAYER, and UNIT_FIELD_TARGET.

◆ EffectKillCredit()

void Spell::EffectKillCredit ( SpellEffIndex  effIndex)
5683{
5685 return;
5686
5687 if (!unitTarget)
5688 return;
5689
5691 if (!player)
5692 {
5693 return;
5694 }
5695
5696 int32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5697 if (!creatureEntry)
5698 {
5699 if (m_spellInfo->Id == 42793) // Burn Body
5700 creatureEntry = 24008; // Fallen Combatant
5701 }
5702
5703 if (creatureEntry)
5704 player->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);
5705}
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition: Player.cpp:12681

References effectHandleMode, SpellInfo::Effects, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), SpellInfo::Id, m_spellInfo, Player::RewardPlayerAndGroupAtEvent(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectKillCreditPersonal()

void Spell::EffectKillCreditPersonal ( SpellEffIndex  effIndex)
5669{
5671 return;
5672
5673 if (!unitTarget)
5674 return;
5675
5677 {
5678 player->KilledMonsterCredit(m_spellInfo->Effects[effIndex].MiscValue);
5679 }
5680}

References effectHandleMode, SpellInfo::Effects, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectKnockBack()

void Spell::EffectKnockBack ( SpellEffIndex  effIndex)
4960{
4962 return;
4963
4964 if (!unitTarget)
4965 return;
4966
4967 // Xinef: allow entry specific spells to skip those checks
4968 if (m_spellInfo->Effects[effIndex].TargetA.GetCheckType() != TARGET_CHECK_ENTRY && m_spellInfo->Effects[effIndex].TargetB.GetCheckType() != TARGET_CHECK_ENTRY)
4969 {
4971 return;
4972
4973 if (unitTarget->GetVehicle())
4974 return;
4975
4976 if (Creature* creatureTarget = unitTarget->ToCreature())
4977 if (creatureTarget->isWorldBoss() || creatureTarget->IsDungeonBoss() || creatureTarget->IsImmuneToKnockback() || unitTarget->ToCreature()->GetCreatureType() == CREATURE_TYPE_GIANT)
4978 return;
4979 }
4980
4981 // Spells with SPELL_EFFECT_KNOCK_BACK(like Thunderstorm) can't knoback target if target has ROOT
4983 return;
4984
4985 // Instantly interrupt non melee spells being casted
4988
4989 float ratio = 0.1f;
4990 float speedxy = float(m_spellInfo->Effects[effIndex].MiscValue) * ratio;
4991 float speedz = float(damage) * ratio;
4992 if (speedxy <= 0.1f && speedz <= 0.1f)
4993 return;
4994
4995 float x, y;
4996 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_KNOCK_BACK_DEST)
4997 {
4998 if (m_targets.HasDst())
4999 destTarget->GetPosition(x, y);
5000 else
5001 return;
5002 }
5003 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_KNOCK_BACK)
5004 {
5005 m_caster->GetPosition(x, y);
5006 }
5007
5008 unitTarget->KnockbackFrom(x, y, speedxy, speedz);
5009
5011 {
5012 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5013 }
5014}
@ SPELL_EFFECT_KNOCK_BACK_DEST
Definition: SharedDefines.h:922
@ CREATURE_TYPE_GIANT
Definition: SharedDefines.h:2632
@ CREATURE_TYPE_BEAST
Definition: SharedDefines.h:2628
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:4088
uint32 GetCreatureType() const
Definition: Unit.cpp:15096
void KnockbackFrom(float x, float y, float speedXY, float speedZ)
Definition: Unit.cpp:19047

References CREATURE_TYPE_BEAST, CREATURE_TYPE_GIANT, damage, destTarget, effectHandleMode, SpellInfo::Effects, Unit::GetCreatureType(), Position::GetPosition(), Object::GetTypeId(), Unit::GetVehicle(), SpellCastTargets::HasDst(), Unit::HasUnitState(), Unit::InterruptNonMeleeSpells(), Unit::IsNonMeleeSpellCast(), Unit::IsVehicle(), Unit::KnockbackFrom(), m_caster, m_spellInfo, m_targets, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_KNOCK_BACK_DEST, sScriptMgr, TARGET_CHECK_ENTRY, Object::ToCreature(), Object::ToPlayer(), TYPEID_PLAYER, UNIT_STATE_ROOT, and unitTarget.

◆ EffectLeap()

void Spell::EffectLeap ( SpellEffIndex  effIndex)
4686{
4688 return;
4689
4690 if (!unitTarget || unitTarget->IsInFlight())
4691 return;
4692
4693 if (!m_targets.HasDst())
4694 return;
4695
4696 Position dstpos = destTarget->GetPosition();
4698}
void NearTeleportTo(Position &pos, bool casting=false, bool vehicleTeleport=false, bool withPet=false, bool removeTransport=false)
Definition: Unit.cpp:19885

References destTarget, effectHandleMode, Position::GetOrientation(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SpellCastTargets::HasDst(), Unit::IsInFlight(), m_caster, m_targets, Unit::NearTeleportTo(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectLeapBack()

void Spell::EffectLeapBack ( SpellEffIndex  effIndex)
5017{
5019 return;
5020
5021 if (!unitTarget)
5022 return;
5023
5024 float speedxy = m_spellInfo->Effects[effIndex].MiscValue / 10.0f;
5025 float speedz = damage / 10.0f;
5026 //1891: Disengage
5028
5030 {
5031 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
5032 }
5033
5034 // xinef: changes fall time
5037}
@ SPELLFAMILY_HUNTER
Definition: SharedDefines.h:3537
void JumpTo(float speedXY, float speedZ, bool forward=true)
Definition: Unit.cpp:19418

References damage, effectHandleMode, SpellInfo::Effects, GameTime::GetGameTime(), Position::GetPositionZ(), Object::GetTypeId(), Unit::JumpTo(), m_caster, m_spellInfo, Player::SetFallInformation(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELLFAMILY_HUNTER, SpellInfo::SpellFamilyName, sScriptMgr, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectLearnPetSpell()

void Spell::EffectLearnPetSpell ( SpellEffIndex  effIndex)
3233{
3235 return;
3236
3237 if (!unitTarget)
3238 return;
3239
3240 if (unitTarget->ToPlayer())
3241 {
3242 EffectLearnSpell(effIndex);
3243 return;
3244 }
3245 Pet* pet = unitTarget->ToPet();
3246 if (!pet)
3247 return;
3248
3249 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell);
3250 if (!learn_spellproto)
3251 return;
3252
3253 pet->learnSpell(learn_spellproto->Id);
3255 pet->GetOwner()->PetSpellInitialize();
3256}
bool learnSpell(uint32 spell_id)
Definition: Pet.cpp:1912
void EffectLearnSpell(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:2519

References effectHandleMode, EffectLearnSpell(), SpellInfo::Effects, Pet::GetOwner(), SpellInfo::Id, Pet::learnSpell(), m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellMgr, Unit::ToPet(), Object::ToPlayer(), and unitTarget.

Referenced by EffectLearnSpell().

◆ EffectLearnSkill()

void Spell::EffectLearnSkill ( SpellEffIndex  effIndex)
2750{
2752 return;
2753
2755 return;
2756
2757 if (damage < 0)
2758 return;
2759
2760 uint32 skillid = m_spellInfo->Effects[effIndex].MiscValue;
2761 uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
2762 unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), skillval ? skillval : 1, damage * 75);
2763}
uint16 GetPureSkillValue(uint32 skill) const
Definition: Player.cpp:5458
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal)
Definition: Player.cpp:5272

References damage, effectHandleMode, SpellInfo::Effects, Player::GetPureSkillValue(), Object::GetTypeId(), m_spellInfo, Player::SetSkill(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectLearnSpell()

void Spell::EffectLearnSpell ( SpellEffIndex  effIndex)
2520{
2522 return;
2523
2524 if (!unitTarget)
2525 return;
2526
2528 {
2529 if (unitTarget->ToPet())
2530 EffectLearnPetSpell(effIndex);
2531 return;
2532 }
2533
2534 Player* player = unitTarget->ToPlayer();
2535
2536 uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : m_spellInfo->Effects[effIndex].TriggerSpell;
2537 player->learnSpell(spellToLearn);
2538
2539 LOG_DEBUG("spells.aura", "Spell: Player {} has learned spell {} from Npc {}",
2540 player->GetGUID().ToString(), spellToLearn, m_caster->GetGUID().ToString());
2541}
void learnSpell(uint32 spellId, bool temporary=false, bool learnFromSkill=false)
Definition: Player.cpp:3270
void EffectLearnPetSpell(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:3232

References damage, effectHandleMode, EffectLearnPetSpell(), SpellInfo::Effects, Object::GetGUID(), Object::GetTypeId(), SpellInfo::Id, Player::learnSpell(), LOG_DEBUG, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), Object::ToPlayer(), ObjectGuid::ToString(), TYPEID_PLAYER, and unitTarget.

Referenced by EffectLearnPetSpell().

◆ EffectMilling()

void Spell::EffectMilling ( SpellEffIndex  effIndex)
5496{
5498 return;
5499
5501 return;
5502
5503 Player* p_caster = m_caster->ToPlayer();
5505 return;
5506
5507 if (itemTarget->GetCount() < 5)
5508 return;
5509
5510 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
5511 {
5512 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
5513 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5514 p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
5515 }
5516
5518}
@ LOOT_MILLING
Definition: LootMgr.h:88
@ CONFIG_SKILL_MILLING
Definition: IWorld.h:97
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition: Player.cpp:7729
bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator=1)
Definition: PlayerUpdates.cpp:719

References CONFIG_SKILL_MILLING, effectHandleMode, ItemTemplate::Flags, Item::GetCount(), Object::GetGUID(), Player::GetPureSkillValue(), Item::GetTemplate(), Object::GetTypeId(), ITEM_FLAG_IS_MILLABLE, itemTarget, LOOT_MILLING, m_caster, ItemTemplate::RequiredSkillRank, Player::SendLoot(), SKILL_INSCRIPTION, SPELL_EFFECT_HANDLE_HIT_TARGET, sWorld, Object::ToPlayer(), TYPEID_PLAYER, and Player::UpdateGatherSkill().

◆ EffectModifyThreatPercent()

void Spell::EffectModifyThreatPercent ( SpellEffIndex  effIndex)
5329{
5331 return;
5332
5333 if (!unitTarget)
5334 return;
5335
5337}
void ModifyThreatByPercent(Unit *victim, int32 percent)
Definition: ThreatMgr.cpp:508
ThreatMgr & GetThreatMgr()
Definition: Unit.h:1487

References damage, effectHandleMode, Unit::GetThreatMgr(), m_caster, ThreatMgr::ModifyThreatByPercent(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectNULL()

void Spell::EffectNULL ( SpellEffIndex  effIndex)
243{
244 LOG_DEBUG("spells.aura", "WORLD: Spell Effect DUMMY");
245}

References LOG_DEBUG.

Referenced by EffectPull().

◆ EffectOpenLock()

void Spell::EffectOpenLock ( SpellEffIndex  effIndex)
Todo:
: Add script for spell 41920 - Filling, becouse server it freze when use this spell
2064{
2066 return;
2067
2069 {
2070 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No Player Caster!");
2071 return;
2072 }
2073
2074 Player* player = m_caster->ToPlayer();
2075
2076 uint32 lockId = 0;
2077 ObjectGuid guid;
2078
2079 // Get lockId
2080 if (gameObjTarget)
2081 {
2082 GameObjectTemplate const* goInfo = gameObjTarget->GetGOInfo();
2083 // Arathi Basin banner opening. /// @todo: Verify correctness of this check
2084 if ((goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune) ||
2085 (goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK))
2086 {
2087 //CanUseBattlegroundObject() already called in CheckCast()
2088 // in battleground check
2089 if (Battleground* bg = player->GetBattleground())
2090 {
2091 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2092 return;
2093 }
2094 }
2095 else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
2096 {
2097 //CanUseBattlegroundObject() already called in CheckCast()
2098 // in battleground check
2099 if (Battleground* bg = player->GetBattleground())
2100 {
2101 if (bg->GetBgTypeID(true) == BATTLEGROUND_EY)
2102 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2103 return;
2104 }
2105 }
2106 else if (m_spellInfo->Id == 1842 && gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP)
2107 {
2110 {
2112 }
2113 return;
2114 }
2116 // handle outdoor pvp object opening, return true if go was registered for handling
2117 // these objects must have been spawned by outdoorpvp!
2118 else if (gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr->HandleOpenGo(player, gameObjTarget))
2119 return;
2120 lockId = goInfo->GetLockId();
2121 guid = gameObjTarget->GetGUID();
2122 }
2123 else if (itemTarget)
2124 {
2125 lockId = itemTarget->GetTemplate()->LockID;
2126 guid = itemTarget->GetGUID();
2127 }
2128 else
2129 {
2130 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No GameObject/Item Target!");
2131 return;
2132 }
2133
2134 SkillType skillId = SKILL_NONE;
2135 int32 reqSkillValue = 0;
2136 int32 skillValue;
2137
2138 SpellCastResult res = CanOpenLock(effIndex, lockId, skillId, reqSkillValue, skillValue);
2139 if (res != SPELL_CAST_OK)
2140 {
2141 SendCastResult(res);
2142 return;
2143 }
2144
2145 if (gameObjTarget)
2146 SendLoot(guid, LOOT_SKINNING);
2147 else if (itemTarget)
2148 {
2150 if (Player* itemOwner = itemTarget->GetOwner())
2151 itemTarget->SetState(ITEM_CHANGED, itemOwner);
2152 }
2153
2154 // not allow use skill grow at item base open
2155 if (!m_CastItem && skillId != SKILL_NONE)
2156 {
2157 // update skill if really known
2158 if (uint32 pureSkillValue = player->GetPureSkillValue(skillId))
2159 {
2160 if (gameObjTarget)
2161 {
2162 // Allow one skill-up until respawned
2163 if (!gameObjTarget->IsInSkillupList(player->GetGUID()))
2164 {
2166 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2167 }
2168
2169 }
2170 else if (itemTarget)
2171 {
2172 // Do one skill-up
2173 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2174 }
2175 }
2176 }
2178}
@ GO_JUST_DEACTIVATED
Definition: GameObject.h:114
@ ITEM_CHANGED
Definition: Item.h:210
@ ITEM_FIELD_FLAG_UNLOCKED
Definition: ItemTemplate.h:111
@ ITEM_FIELD_FLAGS
Definition: UpdateFields.h:42
@ LOOT_SKINNING
Definition: LootMgr.h:86
#define sOutdoorPvPMgr
Definition: OutdoorPvPMgr.h:103
@ GAMEOBJECT_TYPE_BUTTON
Definition: SharedDefines.h:1561
@ GAMEOBJECT_TYPE_FLAGSTAND
Definition: SharedDefines.h:1584
@ GAMEOBJECT_TYPE_GOOBER
Definition: SharedDefines.h:1570
@ BATTLEGROUND_EY
Definition: SharedDefines.h:3487
Unit * GetOwner() const
Definition: GameObject.cpp:1238
void AddToSkillupList(ObjectGuid playerGuid)
Definition: GameObject.cpp:3059
bool IsInSkillupList(ObjectGuid playerGuid) const
Definition: GameObject.cpp:3065
LootState getLootState() const
Definition: GameObject.h:225
void SetLootState(LootState s, Unit *unit=nullptr)
Definition: GameObject.cpp:2433
Definition: GameObjectData.h:32
uint32 GetAutoCloseTime() const
Definition: GameObjectData.h:511
uint32 noDamageImmune
Definition: GameObjectData.h:49
struct GameObjectTemplate::@227::@230 button
uint32 losOK
Definition: GameObjectData.h:65
struct GameObjectTemplate::@227::@238 goober
uint32 GetLockId() const
Definition: GameObjectData.h:428
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition: Item.cpp:715
Definition: Object.h:100
void ExecuteLogEffectOpenLock(uint8 effIndex, Object *obj)
Definition: Spell.cpp:5124
void SendLoot(ObjectGuid guid, LootType loottype)
Definition: SpellEffects.cpp:1997

References GameObject::AddToSkillupList(), BATTLEGROUND_EY, GameObjectTemplate::button, CanOpenLock(), effectHandleMode, ExecuteLogEffectOpenLock(), GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_FLAGSTAND, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_TRAP, gameObjTarget, GameObjectTemplate::GetAutoCloseTime(), Player::GetBattleground(), GameObject::GetGOInfo(), Object::GetGUID(), GameObjectTemplate::GetLockId(), GameObject::getLootState(), GameObject::GetOwner(), Item::GetOwner(), Player::GetPureSkillValue(), Item::GetTemplate(), Object::GetTypeId(), GO_JUST_DEACTIVATED, GameObjectTemplate::goober, SpellInfo::Id, IN_MILLISECONDS, GameObject::IsInSkillupList(), ITEM_CHANGED, ITEM_FIELD_FLAG_UNLOCKED, ITEM_FIELD_FLAGS, itemTarget, ItemTemplate::LockID, LOG_DEBUG, LOOT_SKINNING, GameObjectTemplate::losOK, m_caster, m_CastItem, m_spellInfo, GameObjectTemplate::noDamageImmune, SendCastResult(), SendLoot(), Object::SetFlag(), GameObject::SetLootState(), GameObject::SetRespawnTime(), Item::SetState(), SKILL_NONE, sOutdoorPvPMgr, SPELL_CAST_OK, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), GameObjectTemplate::type, TYPEID_PLAYER, and Player::UpdateGatherSkill().

◆ EffectParry()

void Spell::EffectParry ( SpellEffIndex  effIndex)
4668{
4670 return;
4671
4673 m_caster->ToPlayer()->SetCanParry(true);
4674}
void SetCanParry(bool value)
Definition: Player.cpp:13072

References effectHandleMode, Object::GetTypeId(), m_caster, Player::SetCanParry(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), and TYPEID_PLAYER.

◆ EffectPersistentAA()

void Spell::EffectPersistentAA ( SpellEffIndex  effIndex)
1833{
1835 return;
1836
1837 if (!m_spellAura)
1838 {
1840 float radius = m_spellInfo->Effects[effIndex].CalcRadius(caster);
1841
1842 // Caster not in world, might be spell triggered from aura removal
1843 if (!caster->IsInWorld() || !caster->FindMap() || !ObjectAccessor::GetUnit(*caster, caster->GetGUID())) // pussywizard: temporary crash fix (FindMap and GetUnit are mine)
1844 return;
1845 DynamicObject* dynObj = new DynamicObject(false);
1846 if (!dynObj->CreateDynamicObject(caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_AREA_SPELL))
1847 {
1848 delete dynObj;
1849 return;
1850 }
1851
1853 {
1854 m_spellAura = aura;
1857 }
1858 else
1859 return;
1860 }
1861
1864}
@ DYNAMIC_OBJECT_AREA_SPELL
Definition: DynamicObject.h:30
#define MAX_EFFECT_MASK
Definition: DBCStructure.h:1638
DynamicObject * GetDynobjOwner() const
Definition: SpellAuras.h:109
static Aura * TryCreate(SpellInfo const *spellproto, uint8 effMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemGUID=ObjectGuid::Empty)
Definition: SpellAuras.cpp:352

References Aura::_ApplyEffectForTargets(), Aura::_RegisterForTargets(), ASSERT, DynamicObject::CreateDynamicObject(), destTarget, DYNAMIC_OBJECT_AREA_SPELL, SpellValue::EffectBasePoints, effectHandleMode, SpellInfo::Effects, WorldObject::FindMap(), Map::GenerateLowGuid(), Aura::GetDynobjOwner(), Object::GetEntry(), Object::GetGUID(), WorldObject::GetMap(), ObjectAccessor::GetUnit(), SpellInfo::Id, Object::IsInWorld(), m_caster, m_originalCaster, m_spellAura, m_spellInfo, m_spellValue, m_triggeredByAuraSpell, MAX_EFFECT_MASK, Aura::SetTriggeredByAuraSpellInfo(), SPELL_EFFECT_HANDLE_HIT, TriggeredByAuraSpellData::spellInfo, Aura::TryCreate(), and WORLD_TRIGGER.

◆ EffectPickPocket()

void Spell::EffectPickPocket ( SpellEffIndex  effIndex)

◆ EffectPlayMusic()

void Spell::EffectPlayMusic ( SpellEffIndex  effIndex)
6099{
6101 return;
6102
6103 if (!unitTarget)
6104 return;
6105
6106 Player* player = unitTarget->ToPlayer();
6107 if (!player)
6108 {
6109 return;
6110 }
6111
6112 uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
6113
6114 if (!sSoundEntriesStore.LookupEntry(soundid))
6115 {
6116 LOG_ERROR("spells.effect", "EffectPlayMusic: Sound (Id: {}) not exist in spell {}.", soundid, m_spellInfo->Id);
6117 return;
6118 }
6119
6121}
DBCStorage< SoundEntriesEntry > sSoundEntriesStore(SoundEntriesfmt)
Definition: MiscPackets.h:58

References effectHandleMode, SpellInfo::Effects, SpellInfo::Id, LOG_ERROR, m_spellInfo, Player::SendDirectMessage(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSoundEntriesStore, Object::ToPlayer(), and unitTarget.

◆ EffectPlaySound()

void Spell::EffectPlaySound ( SpellEffIndex  effIndex)
6152{
6154 return;
6155
6156 if (!unitTarget)
6157 return;
6158
6159 Player* player = unitTarget->ToPlayer();
6160 if (!player)
6161 {
6162 return;
6163 }
6164
6165 switch (m_spellInfo->Id)
6166 {
6167 case 58730: // Restricted Flight Area
6168 case 58600: // Restricted Flight Area
6170 break;
6171 default:
6172 break;
6173 }
6174
6175 uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
6176
6177 if (!sSoundEntriesStore.LookupEntry(soundId))
6178 {
6179 LOG_ERROR("spells.effect", "EffectPlayerSound: Sound (Id: {}) not exist in spell {}.", soundId, m_spellInfo->Id);
6180 return;
6181 }
6182
6183 player->PlayDirectSound(soundId, player);
6184}
@ LANG_ZONE_NOFLYZONE
Definition: Language.h:753
Definition: Chat.h:39
void SendNotification(std::string_view str)
Definition: Chat.cpp:107
void PlayDirectSound(uint32 sound_id, Player *target=nullptr)
Definition: Object.cpp:2887

References effectHandleMode, SpellInfo::Effects, Player::GetSession(), SpellInfo::Id, LANG_ZONE_NOFLYZONE, LOG_ERROR, m_spellInfo, WorldObject::PlayDirectSound(), ChatHandler::SendNotification(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSoundEntriesStore, Object::ToPlayer(), and unitTarget.

◆ EffectPowerBurn()

void Spell::EffectPowerBurn ( SpellEffIndex  effIndex)
1419{
1421 return;
1422
1423 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1424 return;
1425
1426 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1427
1429 return;
1430
1431 // burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn)
1432 if (m_spellInfo->Id == 8129)
1433 {
1436 damage = std::min(damage, maxDamage);
1437
1438 // Remove fear
1440 }
1441
1442 int32 power = damage;
1443 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1444 if (PowerType == POWER_MANA)
1445 power -= unitTarget->GetSpellCritDamageReduction(power);
1446
1447 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -power));
1448
1449 // NO - Not a typo - EffectPowerBurn uses effect value multiplier - not effect damage multiplier
1450 float dmgMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1451
1452 // add log data before multiplication (need power amount, not damage)
1453 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, 0.0f);
1454
1455 newDamage = int32(newDamage * dmgMultiplier);
1456
1457 m_damage += newDamage;
1458}
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition: Unit.cpp:14065
uint32 GetSpellCritDamageReduction(uint32 damage) const
Definition: Unit.h:930
void ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
Definition: Spell.cpp:5093

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectTakeTargetPower(), Unit::GetMaxPower(), Unit::GetSpellCritDamageReduction(), Unit::HasActivePowerType(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_damage, m_originalCaster, m_spellInfo, MAX_POWERS, Unit::ModifyPower(), POWER_MANA, Unit::RemoveAurasByType(), SPELL_AURA_MOD_FEAR, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectPowerDrain()

void Spell::EffectPowerDrain ( SpellEffIndex  effIndex)
1340{
1342 return;
1343
1344 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1345 return;
1346
1347 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1348
1350 return;
1351
1352 // add spell damage bonus
1355
1356 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1357 int32 power = damage;
1358 if (PowerType == POWER_MANA)
1359 power -= unitTarget->GetSpellCritDamageReduction(power);
1360
1361 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -int32(power)));
1362
1363 float gainMultiplier = 0.0f;
1364
1365 // Don`t restore from self drain
1366 if (m_caster != unitTarget)
1367 {
1368 gainMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1369
1370 int32 gain = int32(newDamage * gainMultiplier);
1371
1373 }
1374 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, gainMultiplier);
1375}

References damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), ExecuteLogEffectTakeTargetPower(), Unit::GetSpellCritDamageReduction(), Unit::HasActivePowerType(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_originalCaster, m_spellInfo, MAX_POWERS, Unit::ModifyPower(), POWER_MANA, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), and unitTarget.

◆ EffectProficiency()

void Spell::EffectProficiency ( SpellEffIndex  effIndex)
2290{
2292 return;
2293
2295 return;
2296 Player* p_target = m_caster->ToPlayer();
2297
2299 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask))
2300 {
2301 p_target->AddWeaponProficiency(subClassMask);
2303 }
2304 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & subClassMask))
2305 {
2306 p_target->AddArmorProficiency(subClassMask);
2308 }
2309}
uint32 GetArmorProficiency() const
Definition: Player.h:1352
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
Definition: Player.cpp:10057
uint32 GetWeaponProficiency() const
Definition: Player.h:1351
void AddArmorProficiency(uint32 newflag)
Definition: Player.h:1350
void AddWeaponProficiency(uint32 newflag)
Definition: Player.h:1349
int32 EquippedItemSubClassMask
Definition: SpellInfo.h:376

References Player::AddArmorProficiency(), Player::AddWeaponProficiency(), effectHandleMode, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Player::GetArmorProficiency(), Object::GetTypeId(), Player::GetWeaponProficiency(), ITEM_CLASS_ARMOR, ITEM_CLASS_WEAPON, m_caster, m_spellInfo, Player::SendProficiency(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), and TYPEID_PLAYER.

◆ EffectProspecting()

void Spell::EffectProspecting ( SpellEffIndex  effIndex)

◆ EffectPull()

void Spell::EffectPull ( SpellEffIndex  effIndex)
Todo:
: create a proper pull towards distract spell center for distract
2662{
2664 EffectNULL(effIndex);
2665}
void EffectNULL(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:242

References EffectNULL().

◆ EffectPullTowards()

void Spell::EffectPullTowards ( SpellEffIndex  effIndex)
5102{
5104 return;
5105
5106 if (!unitTarget)
5107 return;
5108
5109 Position pos;
5110 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
5111 {
5112 if (m_targets.HasDst())
5113 pos.Relocate(*destTarget);
5114 else
5115 return;
5116 }
5117 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_PULL_TOWARDS)
5118 {
5119 // Xinef: Increase Z position a little bit, should protect from falling through textures
5121 }
5122
5123 float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) ? float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f : 30.f;
5124 float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
5125
5126 unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ);
5127
5129 {
5130 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5131 }
5132}
@ SPELL_EFFECT_PULL_TOWARDS_DEST
Definition: SharedDefines.h:923
double gravity
Definition: MovementUtil.cpp:24
void Relocate(float x, float y)
Definition: Position.h:73

References destTarget, effectHandleMode, SpellInfo::Effects, WorldObject::GetDistance(), Unit::GetMotionMaster(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Object::GetTypeId(), Movement::gravity, SpellCastTargets::HasDst(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), Position::Relocate(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_PULL_TOWARDS_DEST, sScriptMgr, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectQuestClear()

void Spell::EffectQuestClear ( SpellEffIndex  effIndex)
5040{
5042 return;
5043
5044 if (!unitTarget)
5045 return;
5046
5047 Player* player = unitTarget->ToPlayer();
5048 if (!player)
5049 {
5050 return;
5051 }
5052
5053 uint32 quest_id = m_spellInfo->Effects[effIndex].MiscValue;
5054
5055 Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
5056
5057 if (!quest)
5058 return;
5059
5060 // Player has never done this quest
5061 if (player->GetQuestStatus(quest_id) == QUEST_STATUS_NONE)
5062 return;
5063
5064 // remove all quest entries for 'entry' from quest log
5065 for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
5066 {
5067 uint32 logQuest = player->GetQuestSlotQuestId(slot);
5068 if (logQuest == quest_id)
5069 {
5070 player->SetQuestSlot(slot, 0);
5071
5072 // we ignore unequippable quest items in this case, it's still be equipped
5073 player->TakeQuestSourceItem(logQuest, false);
5074
5075 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
5076 {
5077 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
5078 player->UpdatePvPState();
5079 }
5080 }
5081 }
5082
5083 player->RemoveRewardedQuest(quest_id);
5084 player->RemoveActiveQuest(quest_id, false);
5085}
@ QUEST_FLAGS_FLAGS_PVP
Definition: QuestDef.h:145
#define MAX_QUEST_LOG_SIZE
Definition: QuestDef.h:33
@ QUEST_STATUS_NONE
Definition: QuestDef.h:100
bool IsHostile
Definition: Player.h:360
bool IsInHostileArea
Definition: Player.h:361
bool HasPvPForcingQuest() const
Definition: PlayerQuest.cpp:2489
void UpdatePvPState()
Definition: PlayerUpdates.cpp:1390
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition: Player.h:1473
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition: Player.h:1477
PvPInfo pvpInfo
Definition: Player.h:1823
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition: PlayerQuest.cpp:1357
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition: PlayerQuest.cpp:1489
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition: PlayerQuest.cpp:1424
void RemoveRewardedQuest(uint32 questId, bool update=true)
Definition: PlayerQuest.cpp:1507
Definition: QuestDef.h:209
bool HasFlag(uint32 flag) const
Definition: QuestDef.h:220

References effectHandleMode, SpellInfo::Effects, Player::GetQuestSlotQuestId(), Player::GetQuestStatus(), Quest::HasFlag(), Player::HasPvPForcingQuest(), PvPInfo::IsHostile, PvPInfo::IsInHostileArea, m_spellInfo, MAX_QUEST_LOG_SIZE, Player::pvpInfo, QUEST_FLAGS_FLAGS_PVP, QUEST_STATUS_NONE, Player::RemoveActiveQuest(), Player::RemoveRewardedQuest(), Player::SetQuestSlot(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Player::TakeQuestSourceItem(), Object::ToPlayer(), unitTarget, and Player::UpdatePvPState().

◆ EffectQuestComplete()

void Spell::EffectQuestComplete ( SpellEffIndex  effIndex)
4727{
4729 return;
4730
4731 if (!unitTarget)
4732 return;
4733
4734 Player* player = unitTarget->ToPlayer();
4735 if (!player)
4736 {
4737 return;
4738 }
4739
4740 uint32 questId = m_spellInfo->Effects[effIndex].MiscValue;
4741 if (questId)
4742 {
4743 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
4744 if (!quest)
4745 return;
4746
4747 uint16 logSlot = player->FindQuestSlot(questId);
4748 if (logSlot < MAX_QUEST_LOG_SIZE)
4749 player->AreaExploredOrEventHappens(questId);
4750 else if (player->CanTakeQuest(quest, false)) // never rewarded before
4751 player->CompleteQuest(questId); // quest not in log - for internal use
4752 }
4753}
uint16 FindQuestSlot(uint32 quest_id) const
Definition: PlayerQuest.cpp:1776
bool CanTakeQuest(Quest const *quest, bool msg)
Definition: PlayerQuest.cpp:251
void CompleteQuest(uint32 quest_id)
Definition: PlayerQuest.cpp:597
void AreaExploredOrEventHappens(uint32 questId)
Definition: PlayerQuest.cpp:1785

References Player::AreaExploredOrEventHappens(), Player::CanTakeQuest(), Player::CompleteQuest(), effectHandleMode, SpellInfo::Effects, Player::FindQuestSlot(), m_spellInfo, MAX_QUEST_LOG_SIZE, sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectQuestFail()

void Spell::EffectQuestFail ( SpellEffIndex  effIndex)
5708{
5710 return;
5711
5712 if (!unitTarget)
5713 return;
5714
5715 if (Player* player = unitTarget->ToPlayer())
5716 {
5717 player->FailQuest(m_spellInfo->Effects[effIndex].MiscValue);
5718 }
5719}

References effectHandleMode, SpellInfo::Effects, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectQuestStart()

void Spell::EffectQuestStart ( SpellEffIndex  effIndex)
5722{
5724 return;
5725
5726 if (!unitTarget)
5727 return;
5728
5729 Player* player = unitTarget->ToPlayer();
5730 if (!player)
5731 return;
5732
5733 if (Quest const* quest = sObjectMgr->GetQuestTemplate(m_spellInfo->Effects[effIndex].MiscValue))
5734 {
5735 if (!player->CanTakeQuest(quest, false))
5736 return;
5737
5738 if (quest->IsAutoAccept() && player->CanAddQuest(quest, false))
5739 player->AddQuestAndCheckCompletion(quest, player);
5740
5741 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
5742 }
5743}
void SendQuestGiverQuestDetails(Quest const *quest, ObjectGuid npcGUID, bool activateAccept) const
Definition: GossipDef.cpp:388
bool CanAddQuest(Quest const *quest, bool msg)
Definition: PlayerQuest.cpp:264
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
Definition: PlayerQuest.cpp:420
PlayerMenu * PlayerTalkClass
Definition: Player.h:2215

References Player::AddQuestAndCheckCompletion(), Player::CanAddQuest(), Player::CanTakeQuest(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), m_spellInfo, Player::PlayerTalkClass, PlayerMenu::SendQuestGiverQuestDetails(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectRechargeManaGem()

void Spell::EffectRechargeManaGem ( SpellEffIndex  effIndex)
6241{
6243 return;
6244
6246 return;
6247
6248 Player* player = m_caster->ToPlayer();
6249
6250 if (!player)
6251 return;
6252
6253 uint32 item_id = m_spellInfo->Effects[EFFECT_0].ItemType;
6254
6255 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
6256 if (!pProto)
6257 {
6258 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
6259 return;
6260 }
6261
6262 if (Item* pItem = player->GetItemByEntry(item_id))
6263 {
6264 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
6265 pItem->SetSpellCharges(x, pProto->Spells[x].SpellCharges);
6266 pItem->SetState(ITEM_CHANGED, player);
6267 }
6268}

References EFFECT_0, effectHandleMode, SpellInfo::Effects, EQUIP_ERR_ITEM_NOT_FOUND, Player::GetItemByEntry(), Object::GetTypeId(), ITEM_CHANGED, m_caster, m_spellInfo, MAX_ITEM_PROTO_SPELLS, Player::SendEquipError(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, _Spell::SpellCharges, ItemTemplate::Spells, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectRedirectThreat()

void Spell::EffectRedirectThreat ( SpellEffIndex  effIndex)
5882{
5884 return;
5885
5886 if (unitTarget)
5888}
void SetRedirectThreat(ObjectGuid guid, uint32 pct)
Definition: Unit.h:1686

References damage, effectHandleMode, Object::GetGUID(), m_caster, Unit::SetRedirectThreat(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectRemoveAura()

void Spell::EffectRemoveAura ( SpellEffIndex  effIndex)
6187{
6189 return;
6190
6191 if (!unitTarget)
6192 return;
6193 // there may be need of specifying casterguid of removed auras
6194 unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
6195}

References effectHandleMode, SpellInfo::Effects, m_spellInfo, Unit::RemoveAurasDueToSpell(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectRenamePet()

void Spell::EffectRenamePet ( SpellEffIndex  effIndex)
6087{
6089 return;
6090
6093 return;
6094
6096}
@ UNIT_FIELD_BYTES_2
Definition: UpdateFields.h:161
@ UNIT_CAN_BE_RENAMED
Definition: UnitDefines.h:128
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition: Object.cpp:911
PetType getPetType() const
Definition: Pet.h:52

References effectHandleMode, Pet::getPetType(), Object::GetTypeId(), HUNTER_PET, Unit::IsPet(), Object::SetByteFlag(), SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), TYPEID_UNIT, UNIT_CAN_BE_RENAMED, UNIT_FIELD_BYTES_2, and unitTarget.

◆ EffectReputation()

void Spell::EffectReputation ( SpellEffIndex  effIndex)
4701{
4703 return;
4704
4705 if (!unitTarget)
4706 return;
4707
4708 Player* player = unitTarget->ToPlayer();
4709 if (!player)
4710 {
4711 return;
4712 }
4713
4714 float repChange = static_cast<float>(damage);
4715
4716 uint32 factionId = m_spellInfo->Effects[effIndex].MiscValue;
4717
4718 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
4719 if (!factionEntry)
4720 return;
4721
4722 repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId);
4723 player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
4724}
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
@ REPUTATION_SOURCE_SPELL
Definition: Player.h:245
float CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, float rep, int32 faction, bool noQuestBonus=false)
Definition: Player.cpp:5825
ReputationMgr & GetReputationMgr()
Definition: Player.h:2101
bool ModifyReputation(FactionEntry const *factionEntry, float standing, bool noSpillOver=false, Optional< ReputationRank > repMaxCap={})
Definition: ReputationMgr.h:118
Definition: DBCStructure.h:907

References Player::CalculateReputationGain(), damage, effectHandleMode, SpellInfo::Effects, Player::GetReputationMgr(), m_spellInfo, ReputationMgr::ModifyReputation(), REPUTATION_SOURCE_SPELL, sFactionStore, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectResurrect()

void Spell::EffectResurrect ( SpellEffIndex  effIndex)
4619{
4621 return;
4622
4623 if (!unitTarget)
4624 return;
4625
4626 if (!unitTarget)
4627 return;
4628
4629 Player* target = unitTarget->ToPlayer();
4630 if (!target)
4631 {
4632 return;
4633 }
4634
4635 if (unitTarget->IsAlive() || !unitTarget->IsInWorld())
4636 return;
4637
4638 if (target->isResurrectRequested()) // already have one active request
4639 return;
4640
4641 uint32 health = target->CountPctFromMaxHealth(damage);
4643
4644 ExecuteLogEffectResurrect(effIndex, target);
4645
4647 SendResurrectRequest(target);
4648}
void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
Definition: Player.h:1792
bool isResurrectRequested() const
Definition: Player.h:1804
void ExecuteLogEffectResurrect(uint8 effIndex, Unit *target)
Definition: Spell.cpp:5154
void SendResurrectRequest(Player *target)
Definition: Spell.cpp:5216

References CalculatePct(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, ExecuteLogEffectResurrect(), Object::GetGUID(), WorldLocation::GetMapId(), Unit::GetMaxPower(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Object::IsInWorld(), Player::isResurrectRequested(), m_caster, POWER_MANA, SendResurrectRequest(), Player::setResurrectRequestData(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectResurrectNew()

◆ EffectResurrectPet()

void Spell::EffectResurrectPet ( SpellEffIndex  effIndex)
Todo:
: Better to fail Hunter's "Revive Pet" at cast instead of here when casting ends
5178{
5180 return;
5181
5182 if (damage < 0)
5183 return;
5184
5185 Player* player = m_caster->ToPlayer();
5186 if (!player)
5187 {
5188 return;
5189 }
5190
5191 Pet* pet = player->GetPet();
5192 if (!pet)
5193 {
5194 // Position passed to SummonPet is irrelevant with current implementation,
5195 // pet will be relocated without using these coords in Pet::LoadPetFromDB
5196 player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET, 0s, damage);
5197 return;
5198 }
5199
5201 if (pet->IsAlive())
5202 {
5203 return;
5204 }
5205
5206 // Reposition the pet's corpse before reviving so as not to grab aggro
5207 // We can use a different, more accurate version of GetClosePoint() since we have a pet
5208 float x, y, z; // Will be used later to reposition the pet if we have one
5209 player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
5210 pet->NearTeleportTo(x, y, z, player->GetOrientation());
5211 pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
5214 pet->setDeathState(DeathState::Alive);
5215 pet->ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_POSSESSED))); // xinef: just in case
5217 pet->SetDisplayId(pet->GetNativeDisplayId());
5218
5219 // xinef: restore movement
5220 if (auto ci = pet->GetCharmInfo())
5221 {
5222 ci->SetIsAtStay(false);
5223 ci->SetIsFollowing(false);
5224 }
5225
5227}
#define PET_FOLLOW_DIST
Definition: PetDefines.h:198
@ SUMMON_PET
Definition: PetDefines.h:31
@ UNIT_STATE_POSSESSED
Definition: UnitDefines.h:165
@ UNIT_STATE_ALL_STATE
Definition: UnitDefines.h:199
@ UNIT_DYNFLAG_NONE
Definition: SharedDefines.h:3120
float GetFollowAngle() const override
Definition: TemporarySummon.h:82
bool GetClosePoint(float &x, float &y, float &z, float size, float distance2d=0, float angle=0, WorldObject const *forWho=nullptr, bool force=false) const
Definition: Object.cpp:2696
void setDeathState(DeathState s, bool despawn=false) override
Definition: Pet.cpp:631
void SetDisplayId(uint32 modelId, float displayScale=1.f) override
Definition: Pet.cpp:2421
Pet * SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration=0s, uint32 healthPct=0)
Definition: Player.cpp:8885
void ReplaceAllDynamicFlags(uint32 flag) override
Definition: Unit.h:666
void SetHealth(uint32 val)
Definition: Unit.cpp:15392
uint32 GetNativeDisplayId() const
Definition: Unit.h:1512
void RemoveUnitFlag(UnitFlags flags)
Definition: Unit.h:826

References Unit::ClearUnitState(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, Unit::GetCharmInfo(), WorldObject::GetClosePoint(), Unit::GetCombatReach(), Minion::GetFollowAngle(), Unit::GetNativeDisplayId(), Position::GetOrientation(), Player::GetPet(), Unit::IsAlive(), m_caster, Unit::NearTeleportTo(), PET_FOLLOW_DIST, PET_SAVE_AS_CURRENT, Position::Relocate(), Unit::RemoveUnitFlag(), Unit::ReplaceAllDynamicFlags(), Pet::SavePetToDB(), Pet::setDeathState(), Pet::SetDisplayId(), Unit::SetHealth(), SPELL_EFFECT_HANDLE_HIT, SUMMON_PET, Player::SummonPet(), Object::ToPlayer(), UNIT_DYNFLAG_NONE, UNIT_FLAG_SKINNABLE, UNIT_STATE_ALL_STATE, and UNIT_STATE_POSSESSED.

◆ EffectSanctuary()

void Spell::EffectSanctuary ( SpellEffIndex  effIndex)
4003{
4005 return;
4006
4007 if (!unitTarget)
4008 return;
4009
4011 {
4013 // Xinef: replaced with CombatStop(false)
4016
4017 // Night Elf: Shadowmeld only resets threat temporarily
4018 if (m_spellInfo->Id != 59646)
4020
4022 unitTarget->ToPlayer()->SendAttackSwingCancelAttack(); // melee and ranged forced attack cancel
4023 }
4024 else
4025 {
4026 unitTarget->getHostileRefMgr().UpdateVisibility(m_spellInfo->Id == 59646); // Night Elf: Shadowmeld
4027 unitTarget->CombatStop(true);
4028 }
4029
4030 UnitList targets;
4031 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, unitTarget->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4034 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4035 {
4036 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4037 continue;
4038
4040 {
4041 if ((*iter)->GetCurrentSpell(i) && (*iter)->GetCurrentSpell(i)->m_targets.GetUnitTargetGUID() == unitTarget->GetGUID())
4042 {
4043 SpellInfo const* si = (*iter)->GetCurrentSpell(i)->GetSpellInfo();
4044 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->GetTypeId() == TYPEID_UNIT)
4045 {
4046 Creature* c = (*iter)->ToCreature();
4047 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4048 continue;
4049 }
4050 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4051 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4052 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4053 {
4054 // at least one effect truly targets an unit, interrupt the spell
4055 interrupt = true;
4056 break;
4057 }
4058 if (interrupt)
4059 (*iter)->InterruptSpell(CurrentSpellTypes(i), false);
4060 }
4061 }
4062 }
4063
4064 // Xinef: Set last sanctuary time
4066}
#define CURRENT_MAX_SPELL
Definition: Unit.h:544
void UpdateVisibility(bool checkThreat)
Definition: HostileRefMgr.cpp:236
void addThreatPercent(int32 percent)
Definition: HostileRefMgr.cpp:85
void SendAttackSwingCancelAttack()
Definition: PlayerMisc.cpp:140
void CombatStop(bool includingCast=false)
Definition: Unit.cpp:10368
void RemoveAllAttackers()
Definition: Unit.cpp:10411
bool AttackStop()
Definition: Unit.cpp:10335
virtual bool IsEncounterInProgress() const
Definition: InstanceScript.cpp:122

References HostileRefMgr::addThreatPercent(), Unit::AttackStop(), Unit::CombatStop(), CREATURE_ELITE_WORLDBOSS, CURRENT_FIRST_NON_MELEE_SPELL, CURRENT_MAX_SPELL, effectHandleMode, SpellInfo::Effects, Creature::GetCreatureTemplate(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::getHostileRefMgr(), WorldObject::GetInstanceScript(), Object::GetTypeId(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::InterruptSpell(), Creature::IsDungeonBoss(), InstanceScript::IsEncounterInProgress(), Unit::IsPet(), Creature::isWorldBoss(), Unit::m_lastSanctuaryTime, m_spellInfo, MAX_SPELL_EFFECTS, CreatureTemplate::rank, Unit::RemoveAllAttackers(), Player::SendAttackSwingCancelAttack(), SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_EFFECT_HANDLE_HIT_TARGET, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), Object::ToPlayer(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_STATE_CASTING, unitTarget, HostileRefMgr::UpdateVisibility(), and Cell::VisitAllObjects().

◆ EffectSchoolDMG()

void Spell::EffectSchoolDMG ( SpellEffIndex  effIndex)
Todo:
: should this be put on taken but not done?
328{
330 return;
331
332 if (unitTarget && unitTarget->IsAlive())
333 {
334 bool apply_direct_bonus = true;
336 {
338 {
339 // Meteor like spells (divided damage to targets)
341 {
342 uint32 count = 0;
343 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
344 if (ihit->effectMask & (1 << effIndex))
345 ++count;
346
347 damage /= count; // divide to all targets
348 }
349 break;
350 }
352 {
353 // Shield Slam
354 if (m_spellInfo->SpellFamilyFlags[1] & 0x200 && m_spellInfo->GetCategory() == 1209)
355 {
356 uint8 level = m_caster->GetLevel();
357 // xinef: shield block should increase the limit
358 float limit = m_caster->HasAura(2565) ? 2.0f : 1.0f;
359 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 24.5f * limit), uint32(float(level) * 34.5f * limit));
360
361 damage += int32(m_caster->ApplyEffectModifiers(m_spellInfo, effIndex, float(block_value)));
362 }
363 // Victory Rush
364 else if (m_spellInfo->SpellFamilyFlags[1] & 0x100)
366 // Shockwave
367 else if (m_spellInfo->Id == 46968)
368 {
370 if (pct > 0)
372 break;
373 }
374 break;
375 }
377 {
378 // Incinerate Rank 1 & 2
379 if ((m_spellInfo->SpellFamilyFlags[1] & 0x000040) && m_spellInfo->SpellIconID == 2128)
380 {
381 // Incinerate does more dmg (dmg*0.25) if the target have Immolate debuff.
382 // Check aura state for speed but aura state set not only for Immolate spell
384 {
386 damage += damage / 4;
387 }
388 }
389 // Conflagrate - consumes Immolate or Shadowflame
391 {
392 AuraEffect const* aura = nullptr; // found req. aura for damage calculation
393
395 for (Unit::AuraEffectList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
396 {
397 // for caster applied auras only
398 if ((*i)->GetSpellInfo()->SpellFamilyName != SPELLFAMILY_WARLOCK ||
399 (*i)->GetCasterGUID() != m_caster->GetGUID())
400 continue;
401
402 // Immolate
403 if ((*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x4)
404 {
405 aura = *i; // it selected always if exist
406 break;
407 }
408
409 // Shadowflame
410 if ((*i)->GetSpellInfo()->SpellFamilyFlags[2] & 0x00000002)
411 aura = *i; // remember but wait possible Immolate as primary priority
412 }
413
414 // found Immolate or Shadowflame
415 if (aura)
416 {
417 uint32 pdamage = uint32(std::max(aura->GetAmount(), 0));
418 pdamage = unitTarget->SpellDamageBonusTaken(m_caster, aura->GetSpellInfo(), pdamage, DOT, aura->GetBase()->GetStackAmount());
419 uint32 pct_dir = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 1));
420 uint8 baseTotalTicks = uint8(m_caster->CalcSpellDuration(aura->GetSpellInfo()) / aura->GetSpellInfo()->Effects[EFFECT_0].Amplitude);
421
422 damage += int32(CalculatePct(pdamage * baseTotalTicks, pct_dir));
423
424 uint32 pct_dot = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 2)) / 3;
425 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(int32(CalculatePct(pdamage * baseTotalTicks, pct_dot)));
426
427 apply_direct_bonus = false;
428 // Glyph of Conflagrate
429 if (!m_caster->HasAura(56235))
431
432 break;
433 }
434 }
435 // Shadow Bite
436 else if (m_spellInfo->SpellFamilyFlags[1] & 0x400000)
437 {
439 {
440 if (Player* owner = m_caster->GetOwner()->ToPlayer())
441 {
442 if (AuraEffect* aurEff = owner->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_WARLOCK, 214, 0))
443 {
444 int32 bp0 = aurEff->GetId() == 54037 ? 4 : 8;
445 m_caster->CastCustomSpell(m_caster, 54425, &bp0, nullptr, nullptr, true);
446 }
447 }
448 }
449 }
450 break;
451 }
453 {
454 // Improved Mind Blast (Mind Blast in shadow form bonus)
455 if (m_caster->GetShapeshiftForm() == FORM_SHADOW && (m_spellInfo->SpellFamilyFlags[0] & 0x00002000))
456 {
458 for (Unit::AuraEffectList::const_iterator i = ImprMindBlast.begin(); i != ImprMindBlast.end(); ++i)
459 {
460 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_PRIEST &&
461 ((*i)->GetSpellInfo()->SpellIconID == 95))
462 {
463 int chance = (*i)->GetSpellInfo()->Effects[EFFECT_1].CalcValue(m_caster);
464 if (roll_chance_i(chance))
465 // Mind Trauma
466 m_caster->CastSpell(unitTarget, 48301, true, 0);
467 break;
468 }
469 }
470 }
471 break;
472 }
474 {
475 // Ferocious Bite
476 if (m_caster->GetTypeId() == TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags[0] & 0x000800000) && m_spellInfo->SpellVisual[0] == 6587)
477 {
478 // converts each extra point of energy into ($f1+$AP/410) additional damage
480 float multiple = ap / 410 + m_spellInfo->Effects[effIndex].DamageMultiplier;
481 int32 energy = -(m_caster->ModifyPower(POWER_ENERGY, -30));
482 damage += int32(energy * multiple);
484 }
485 // Wrath
486 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00000001)
487 {
488 // Improved Insect Swarm
489 if (AuraEffect const* aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 1771, 0))
491 AddPct(damage, aurEff->GetAmount());
492 }
493 break;
494 }
496 {
497 // Envenom
498 if (m_spellInfo->SpellFamilyFlags[1] & 0x00000008)
499 {
500 if (Player* player = m_caster->ToPlayer())
501 {
502 // consume from stack dozes not more that have combo-points
503 if (uint32 combo = player->GetComboPoints())
504 {
505 // Lookup for Deadly poison (only attacker applied)
507 {
508 // count consumed deadly poison doses at target
509 bool needConsume = true;
510 uint32 spellId = aurEff->GetId();
511
512 uint32 doses = aurEff->GetBase()->GetStackAmount();
513 if (doses > combo)
514 doses = combo;
515
516 // Master Poisoner
517 Unit::AuraEffectList const& auraList = player->GetAuraEffectsByType(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK);
518 for (Unit::AuraEffectList::const_iterator iter = auraList.begin(); iter != auraList.end(); ++iter)
519 {
520 if ((*iter)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellInfo()->SpellIconID == 1960)
521 {
522 uint32 chance = (*iter)->GetSpellInfo()->Effects[EFFECT_2].CalcValue(m_caster);
523
524 if (chance && roll_chance_i(chance))
525 needConsume = false;
526
527 break;
528 }
529 }
530
531 if (needConsume)
532 for (uint32 i = 0; i < doses; ++i)
534
535 damage *= doses;
536 damage += int32(player->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * combo);
537 }
538
539 // Eviscerate and Envenom Bonus Damage (item set effect)
540 if (m_caster->HasAura(37169))
541 damage += combo * 40;
542 }
543 }
544 }
545 // Eviscerate
546 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00020000)
547 {
549 {
550 if (uint32 combo = m_caster->ToPlayer()->GetComboPoints())
551 {
553 damage += int32(ap * combo * 0.07f);
554
555 // Eviscerate and Envenom Bonus Damage (item set effect)
556 if (m_caster->HasAura(37169))
557 damage += combo * 40;
558 }
559 }
560 }
561 break;
562 }
564 {
565 //Gore
566 if (m_spellInfo->SpellIconID == 1578)
567 {
568 if (m_caster->HasAura(57627)) // Charge 6 sec post-affect
569 damage *= 2;
570 }
571 // Steady Shot
572 else if (m_spellInfo->SpellFamilyFlags[1] & 0x1)
573 {
574 bool found = false;
575 // check dazed affect
577 for (Unit::AuraEffectList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter)
578 {
579 if ((*iter)->GetSpellInfo()->SpellIconID == 15 && (*iter)->GetSpellInfo()->Dispel == 0)
580 {
581 found = true;
582 break;
583 }
584 }
585
587 if (found)
588 damage += m_spellInfo->Effects[EFFECT_1].CalcValue();
589
590 if (Player* caster = m_caster->ToPlayer())
591 {
592 // Add Ammo and Weapon damage plus RAP * 0.1
593 float dmg_min = 0.f;
594 float dmg_max = 0.f;
595 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
596 {
597 dmg_min += caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE, i);
598 dmg_max += caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE, i);
599 }
600
601 if (dmg_max == 0.0f && dmg_min > dmg_max)
602 {
603 damage += int32(dmg_min);
604 }
605 else
606 {
607 damage += irand(int32(dmg_min), int32(dmg_max));
608 }
609 damage += int32(caster->GetAmmoDPS() * caster->GetAttackTime(RANGED_ATTACK) * 0.001f);
610 }
611 }
612 break;
613 }
615 {
616 // Hammer of the Righteous
617 if (m_spellInfo->SpellFamilyFlags[1] & 0x00040000)
618 {
619 // Add main hand dps * effect[2] amount
620 if (Player* player = m_caster->ToPlayer())
621 {
622 float minTotal = 0.f;
623 float maxTotal = 0.f;
624 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
625 {
626 float tmpMin, tmpMax;
627 player->CalculateMinMaxDamage(BASE_ATTACK, false, false, tmpMin, tmpMax, i);
628 minTotal += tmpMin;
629 maxTotal += tmpMax;
630 }
631
632 float average = (minTotal + maxTotal) / 2;
635 }
636 break;
637 }
638 // Shield of Righteousness
639 if (m_spellInfo->SpellFamilyFlags[EFFECT_1] & 0x100000)
640 {
641 uint8 level = m_caster->GetLevel();
642 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 29.5f), uint32(float(level) * 34.5f));
643 if (m_caster->GetAuraEffect(64882, EFFECT_0))
644 block_value += 225;
645 damage += CalculatePct(block_value, m_spellInfo->Effects[EFFECT_1].CalcValue());
646 break;
647 }
648 break;
649 }
650 }
651
652 if (m_originalCaster /*&& damage > 0 Xinef: this can be increased from 0*/ && apply_direct_bonus)
653 {
654 // Xinef: protection
655 if (damage < 0)
656 damage = 0;
657
660 }
661
662 m_damage += damage;
663 }
664}
#define MAX_ITEM_PROTO_DAMAGES
Definition: ItemTemplate.h:621
@ MINDAMAGE
Definition: Unit.h:135
@ MAXDAMAGE
Definition: Unit.h:136
@ FORM_SHADOW
Definition: UnitDefines.h:95
@ SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK
Definition: SpellAuraDefines.h:309
@ SPELL_AURA_PERIODIC_DAMAGE
Definition: SpellAuraDefines.h:66
@ SPELL_AURA_ADD_FLAT_MODIFIER
Definition: SpellAuraDefines.h:170
@ SPELL_AURA_MOD_DECREASE_SPEED
Definition: SpellAuraDefines.h:96
@ SPELL_ATTR0_CU_SHARE_DAMAGE
Definition: SpellInfo.h:179
@ EFFECT_2
Definition: SharedDefines.h:33
@ POWER_ENERGY
Definition: SharedDefines.h:272
@ SPELLFAMILY_PRIEST
Definition: SharedDefines.h:3534
@ AURA_STATE_CONFLAGRATE
Definition: SharedDefines.h:1306
float GetTotalAttackPowerValue(WeaponAttackType attType, Unit *pVictim=nullptr) const
Definition: Unit.cpp:15342
float ApplyEffectModifiers(SpellInfo const *spellProto, uint8 effect_index, float value) const
Definition: Unit.cpp:14743
virtual uint32 GetShieldBlockValue() const =0
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4881
uint32 GetAttackTime(WeaponAttackType att) const
Definition: Unit.h:811
AuraEffect * GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const
Definition: Unit.h:1318
uint8 GetStackAmount() const
Definition: SpellAuras.h:148

References AddPct(), Unit::ApplyEffectModifiers(), ApplyPct(), AURA_STATE_CONFLAGRATE, BASE_ATTACK, Unit::CalcSpellDuration(), CalculatePct(), Unit::CalculateSpellDamage(), Unit::CastCustomSpell(), Unit::CastSpell(), damage, DOT, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, effectHandleMode, SpellInfo::Effects, FORM_SHADOW, AuraEffect::GetAmount(), Unit::GetAttackTime(), Unit::GetAuraEffect(), Unit::GetAuraEffectsByType(), AuraEffect::GetBase(), SpellInfo::GetCategory(), Unit::GetComboPoints(), Unit::GetDummyAuraEffect(), Object::GetGUID(), AuraEffect::GetId(), Unit::GetLevel(), Unit::GetOwner(), Unit::GetShapeshiftForm(), Unit::GetShieldBlockValue(), AuraEffect::GetSpellInfo(), Aura::GetStackAmount(), Unit::GetTotalAttackPowerValue(), Object::GetTypeId(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), SpellInfo::Id, IN_MILLISECONDS, irand(), Unit::IsAlive(), Unit::IsPet(), m_caster, m_damage, m_originalCaster, m_spellInfo, m_spellValue, m_UniqueTargetInfo, MAX_ITEM_PROTO_DAMAGES, MAXDAMAGE, MINDAMAGE, Unit::ModifyPower(), POWER_ENERGY, RANGED_ATTACK, Unit::RemoveAuraFromStack(), Unit::RemoveAurasDueToSpell(), roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_ADD_FLAT_MODIFIER, SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_AURA_PERIODIC_DAMAGE, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), SPELLFAMILY_DRUID, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_PALADIN, SPELLFAMILY_PRIEST, SPELLFAMILY_ROGUE, SPELLFAMILY_WARLOCK, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, SpellInfo::SpellVisual, SpellInfo::TargetAuraState, Object::ToPlayer(), TYPEID_PLAYER, TYPEID_UNIT, and unitTarget.

◆ EffectScriptEffect()

void Spell::EffectScriptEffect ( SpellEffIndex  effIndex)
Todo:
: we must implement hunter pet summon at login there (spell 6962)
3767{
3769 return;
3770
3772
3774 {
3776 {
3777 switch (m_spellInfo->Id)
3778 {
3779 // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell)
3780 case 22539:
3781 case 22972:
3782 case 22975:
3783 case 22976:
3784 case 22977:
3785 case 22978:
3786 case 22979:
3787 case 22980:
3788 case 22981:
3789 case 22982:
3790 case 22983:
3791 case 22984:
3792 case 22985:
3793 {
3794 if (!unitTarget || !unitTarget->IsAlive())
3795 return;
3796
3797 // Onyxia Scale Cloak
3798 if (unitTarget->HasAura(22683))
3799 return;
3800
3801 // Shadow Flame
3802 m_caster->CastSpell(unitTarget, 22682, true);
3803 return;
3804 }
3805 // Plant Warmaul Ogre Banner
3806 case 32307:
3807 if (Player* caster = m_caster->ToPlayer())
3808 {
3809 caster->RewardPlayerAndGroupAtEvent(18388, unitTarget);
3810 if (Creature* target = unitTarget->ToCreature())
3811 {
3812 target->setDeathState(DeathState::Corpse);
3813 target->RemoveCorpse();
3814 }
3815 }
3816 break;
3817 // SOTA defender teleport
3818 case 54640:
3819 {
3820 if (Player* player = unitTarget->ToPlayer())
3821 if (player->GetBattleground() && player->GetBattleground()->GetBgTypeID(true) == BATTLEGROUND_SA)
3822 {
3823 if (GameObject* dportal = player->FindNearestGameObject(192819, 10.0f))
3824 {
3825 BattlegroundSA* bg = ((BattlegroundSA*)player->GetBattleground());
3826 bg->DefendersPortalTeleport(dportal, player);
3827 }
3828 }
3829 return;
3830 }
3831 /*// Mug Transformation
3832 case 41931:
3833 {
3834 if (m_caster->GetTypeId() != TYPEID_PLAYER)
3835 return;
3836
3837 uint8 bag = 19;
3838 uint8 slot = 0;
3839 Item* item = nullptr;
3840
3841 while (bag) // 256 = 0 due to var type
3842 {
3843 item = m_caster->ToPlayer()->GetItemByPos(bag, slot);
3844 if (item && item->GetEntry() == 38587)
3845 break;
3846
3847 ++slot;
3848 if (slot == 39)
3849 {
3850 slot = 0;
3851 ++bag;
3852 }
3853 }
3854 if (bag)
3855 {
3856 if (m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount() == 1) m_caster->ToPlayer()->RemoveItem(bag, slot, true);
3857 else m_caster->ToPlayer()->GetItemByPos(bag, slot)->SetCount(m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount()-1);
3858 // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
3859 m_caster->CastSpell(m_caster, 42518, true);
3860 return;
3861 }
3862 break;
3863 }*/
3864 // Roll Dice - Decahedral Dwarven Dice
3865 case 47770:
3866 {
3867 char buf[128];
3868 const char* gender = "his";
3869 if (m_caster->getGender() > 0)
3870 gender = "her";
3871 snprintf(buf, sizeof(buf), "%s rubs %s [Decahedral Dwarven Dice] between %s hands and rolls. One %u and one %u.", m_caster->GetName().c_str(), gender, gender, urand(1, 10), urand(1, 10));
3872 m_caster->TextEmote(buf);
3873 break;
3874 }
3875 case 52173: // Coyote Spirit Despawn
3876 case 60243: // Blood Parrot Despawn
3879 return;
3880 case 57347: // Retrieving (Wintergrasp RP-GG pickup spell)
3881 {
3883 return;
3884
3886
3887 return;
3888 }
3889 case 57349: // Drop RP-GG (Wintergrasp RP-GG at death drop spell)
3890 {
3892 return;
3893
3894 // Delete item from inventory at death
3896
3897 return;
3898 }
3899 case 58418: // Portal to Orgrimmar
3900 case 58420: // Portal to Stormwind
3901 {
3902 if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER || effIndex != 0)
3903 return;
3904
3905 uint32 spellID = m_spellInfo->Effects[EFFECT_0].CalcValue();
3906 uint32 questID = m_spellInfo->Effects[EFFECT_1].CalcValue();
3907
3909 unitTarget->CastSpell(unitTarget, spellID, true);
3910
3911 return;
3912 }
3913 // Stoneclaw Totem
3914 case 55328: // Rank 1
3915 case 55329: // Rank 2
3916 case 55330: // Rank 3
3917 case 55332: // Rank 4
3918 case 55333: // Rank 5
3919 case 55335: // Rank 6
3920 case 55278: // Rank 7
3921 case 58589: // Rank 8
3922 case 58590: // Rank 9
3923 case 58591: // Rank 10
3924 {
3925 int32 basepoints0 = damage;
3926 // Cast Absorb on totems
3927 for (uint8 slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot)
3928 {
3929 if (!unitTarget->m_SummonSlot[slot])
3930 continue;
3931
3933 if (totem && totem->IsTotem())
3934 {
3935 m_caster->CastCustomSpell(totem, 55277, &basepoints0, nullptr, nullptr, true);
3936 }
3937 }
3938 // Glyph of Stoneclaw Totem
3939 if (AuraEffect* aur = unitTarget->GetAuraEffect(63298, 0))
3940 {
3941 basepoints0 *= aur->GetAmount();
3942 m_caster->CastCustomSpell(unitTarget, 55277, &basepoints0, nullptr, nullptr, true);
3943 }
3944 break;
3945 }
3946 case 61263: // for item Intravenous Healing Potion (44698)
3947 {
3948 if( !m_caster || !unitTarget )
3949 return;
3950
3951 m_caster->CastSpell(m_caster, 61267, true);
3952 m_caster->CastSpell(m_caster, 61268, true);
3953 return;
3954 }
3955 }
3956 break;
3957 }
3958 case SPELLFAMILY_ROGUE:
3959 {
3960 switch( m_spellInfo->Id )
3961 {
3962 // Master of Subtlety
3963 case 31666:
3964 {
3965 if( !unitTarget )
3966 return;
3967
3968 Aura* mos = unitTarget->GetAura(31665);
3969 if( mos )
3970 {
3971 mos->SetMaxDuration(6000);
3972 mos->SetDuration(6000, true);
3973 }
3974
3975 break;
3976 }
3977 // Overkill
3978 case 58428:
3979 {
3980 if( !unitTarget )
3981 return;
3982
3983 Aura* overkill = unitTarget->GetAura(58427);
3984 if( overkill )
3985 {
3986 overkill->SetMaxDuration(20000);
3987 overkill->SetDuration(20000, true);
3988 }
3989
3990 break;
3991 }
3992 }
3993 break;
3994 }
3995 }
3996
3997 // normal DB scripted effect
3998 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectScriptEffect({})", m_spellInfo->Id, effIndex);
4000}
@ QUEST_STATUS_COMPLETE
Definition: QuestDef.h:101
@ BATTLEGROUND_SA
Definition: SharedDefines.h:3489
Class for manage Strand of Ancient battleground.
Definition: BattlegroundSA.h:456
void DefendersPortalTeleport(GameObject *portal, Player *plr)
Definition: BattlegroundSA.cpp:585
void DespawnOrUnsummon(Milliseconds msTimeToDespawn, Seconds forcedRespawnTimer)
Definition: Creature.cpp:2163
virtual void UnSummon(uint32 msTime=0)
Definition: TemporarySummon.cpp:282
GameObject * FindNearestGameObject(uint32 entry, float range, bool onlySpawned=false) const
Definition: Object.cpp:2452
std::string const & GetName() const
Definition: Object.h:449
uint8 getGender() const
Definition: Unit.h:767
bool IsSummon() const
Definition: Unit.h:750
virtual void TextEmote(std::string_view text, WorldObject const *target=nullptr, bool isBossEmote=false)
Definition: Unit.cpp:21029

References BATTLEGROUND_SA, Unit::CastCustomSpell(), Unit::CastSpell(), damage, BattlegroundSA::DefendersPortalTeleport(), Creature::DespawnOrUnsummon(), Player::DestroyItemCount(), EFFECT_0, EFFECT_1, effectHandleMode, SpellInfo::Effects, WorldObject::FindNearestGameObject(), Unit::GetAura(), Unit::GetAuraEffect(), Map::GetCreature(), Unit::getGender(), WorldObject::GetMap(), WorldObject::GetName(), Player::GetQuestStatus(), Object::GetTypeId(), Unit::HasAura(), SpellInfo::Id, Unit::IsAlive(), Unit::IsSummon(), Unit::IsTotem(), LOG_DEBUG, m_caster, m_spellInfo, Unit::m_SummonSlot, MAX_TOTEM_SLOT, QUEST_STATUS_COMPLETE, Map::ScriptsStart(), Aura::SetDuration(), Aura::SetMaxDuration(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SPELLFAMILY_ROGUE, SpellInfo::SpellFamilyName, sSpellScripts, SUMMON_SLOT_TOTEM, Unit::TextEmote(), Object::ToCreature(), Object::ToPlayer(), Unit::ToTempSummon(), TYPEID_PLAYER, TYPEID_UNIT, unitTarget, TempSummon::UnSummon(), and urand().

◆ EffectSelfResurrect()

void Spell::EffectSelfResurrect ( SpellEffIndex  effIndex)
4829{
4831 return;
4832
4833 if (!m_caster || m_caster->IsAlive())
4834 return;
4836 return;
4837 if (!m_caster->IsInWorld())
4838 return;
4839
4840 uint32 health = 0;
4841 uint32 mana = 0;
4842
4843 // flat case
4844 if (damage < 0)
4845 {
4846 health = uint32(-damage);
4847 mana = m_spellInfo->Effects[effIndex].MiscValue;
4848 }
4849 // percent case
4850 else
4851 {
4855 }
4856
4857 Player* player = m_caster->ToPlayer();
4858 player->ResurrectPlayer(0.0f);
4859
4860 player->SetHealth(health);
4861 player->SetPower(POWER_MANA, mana);
4862 player->SetPower(POWER_RAGE, 0);
4863 player->SetPower(POWER_ENERGY, player->GetMaxPower(POWER_ENERGY));
4864
4865 player->SpawnCorpseBones();
4866}
@ POWER_RAGE
Definition: SharedDefines.h:270
void SpawnCorpseBones(bool triggerSave=true)
Definition: Player.cpp:4628
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition: Player.cpp:4415
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool fromRegenerate=false)
Definition: Unit.cpp:15480

References CalculatePct(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, SpellInfo::Effects, Unit::GetMaxPower(), Object::GetTypeId(), Unit::IsAlive(), Object::IsInWorld(), m_caster, m_spellInfo, POWER_ENERGY, POWER_MANA, POWER_RAGE, Player::ResurrectPlayer(), Unit::SetHealth(), Unit::SetPower(), Player::SpawnCorpseBones(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), and TYPEID_PLAYER.

◆ EffectSendEvent()

void Spell::EffectSendEvent ( SpellEffIndex  effIndex)
Todo:
: there should be a possibility to pass dest target to event script
1378{
1379 // we do not handle a flag dropping or clicking on flag in battleground by sendevent system
1382 return;
1383
1384 WorldObject* target = nullptr;
1385
1386 // call events for object target if present
1388 {
1389 if (unitTarget)
1390 target = unitTarget;
1391 else if (gameObjTarget)
1392 target = gameObjTarget;
1393 }
1394 else // if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
1395 {
1396 // let's prevent executing effect handler twice in case when spell effect is capable of targeting an object
1397 // this check was requested by scripters, but it has some downsides:
1398 // now it's impossible to script (using sEventScripts) a cast which misses all targets
1399 // or to have an ability to script the moment spell hits dest (in a case when there are object targets present)
1400 if (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT_MASK))
1401 return;
1402 // some spells have no target entries in dbc and they use focus target
1403 if (focusObject)
1404 target = focusObject;
1406 }
1407
1408 LOG_DEBUG("spells.aura", "Spell ScriptStart {} for spellid {} in EffectSendEvent ", m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
1409
1410 if (ZoneScript* zoneScript = m_caster->GetZoneScript())
1411 zoneScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1412 else if (InstanceScript* instanceScript = m_caster->GetInstanceScript()) // needed in case Player is the caster
1413 instanceScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1414
1415 m_caster->GetMap()->ScriptsStart(sEventScripts, m_spellInfo->Effects[effIndex].MiscValue, m_caster, target);
1416}
ScriptMapMap sEventScripts
Definition: ObjectMgr.cpp:58
@ TARGET_FLAG_UNIT_MASK
Definition: SpellInfo.h:68
@ TARGET_FLAG_GAMEOBJECT_MASK
Definition: SpellInfo.h:70
Definition: Object.h:396
ZoneScript * GetZoneScript() const
Definition: Object.h:528
Definition: ZoneScript.h:27

References effectHandleMode, SpellInfo::Effects, focusObject, gameObjTarget, WorldObject::GetInstanceScript(), WorldObject::GetMap(), WorldObject::GetZoneScript(), SpellInfo::Id, LOG_DEBUG, m_caster, m_spellInfo, Map::ScriptsStart(), sEventScripts, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_UNIT_MASK, and unitTarget.

◆ EffectSendTaxi()

void Spell::EffectSendTaxi ( SpellEffIndex  effIndex)
5088{
5090 return;
5091
5092 if (!unitTarget)
5093 return;
5094
5095 if (Player* player = unitTarget->ToPlayer())
5096 {
5097 player->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
5098 }
5099}

References effectHandleMode, SpellInfo::Effects, SpellInfo::Id, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSkill()

void Spell::EffectSkill ( SpellEffIndex  effIndex)
5521{
5523 return;
5524
5525 LOG_DEBUG("spells.aura", "WORLD: SkillEFFECT");
5526}

References effectHandleMode, LOG_DEBUG, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectSkinning()

void Spell::EffectSkinning ( SpellEffIndex  effIndex)
4869{
4871 return;
4872
4874 return;
4876 return;
4877
4878 Creature* creature = unitTarget->ToCreature();
4879 int32 targetLevel = creature->GetLevel();
4880
4881 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
4882
4886
4887 int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5;
4888
4889 int32 skillValue = m_caster->ToPlayer()->GetPureSkillValue(skill);
4890
4891 // Double chances for elites
4892 m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1);
4893}
@ UNIT_DYNFLAG_LOOTABLE
Definition: SharedDefines.h:3121
bool isElite() const
Definition: Creature.h:108
virtual void SetDynamicFlag(uint32 flag)
Definition: Object.h:120

References effectHandleMode, Creature::GetCreatureTemplate(), Object::GetGUID(), Unit::GetLevel(), Player::GetPureSkillValue(), CreatureTemplate::GetRequiredLootSkill(), Object::GetTypeId(), Creature::isElite(), LOOT_SKINNING, m_caster, Unit::RemoveUnitFlag(), Player::SendLoot(), Object::SetDynamicFlag(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_DYNFLAG_LOOTABLE, UNIT_FLAG_SKINNABLE, unitTarget, and Player::UpdateGatherSkill().

◆ EffectSkinPlayerCorpse()

void Spell::EffectSkinPlayerCorpse ( SpellEffIndex  effIndex)
5552{
5554 return;
5555
5556 LOG_DEBUG("spells.aura", "Effect: SkinPlayerCorpse");
5558 return;
5559
5561}
void RemovedInsignia(Player *looterPlr)
Definition: Player.cpp:7690

References effectHandleMode, Object::GetTypeId(), Unit::IsAlive(), LOG_DEBUG, m_caster, Player::RemovedInsignia(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectSpecCount()

void Spell::EffectSpecCount ( SpellEffIndex  effIndex)
6124{
6126 return;
6127
6128 if (!unitTarget)
6129 return;
6130
6131 if (Player* player = unitTarget->ToPlayer())
6132 {
6133 player->UpdateSpecCount(damage);
6134 }
6135}

References damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSpiritHeal()

void Spell::EffectSpiritHeal ( SpellEffIndex  effIndex)
5533{
5535 return;
5536
5537 /*
5538 if (unitTarget->GetTypeId() != TYPEID_PLAYER)
5539 return;
5540 if (!unitTarget->IsInWorld())
5541 return;
5542
5543 //m_spellInfo->Effects[i].BasePoints; == 99 (percent?)
5544 //unitTarget->ToPlayer()->setResurrect(m_caster->GetGUID(), unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), unitTarget->GetMaxHealth(), unitTarget->GetMaxPower(POWER_MANA));
5545 unitTarget->ToPlayer()->ResurrectPlayer(1.0f);
5546 unitTarget->ToPlayer()->SpawnCorpseBones();
5547 */
5548}

References effectHandleMode, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectStealBeneficialBuff()

void Spell::EffectStealBeneficialBuff ( SpellEffIndex  effIndex)
5564{
5566 return;
5567
5568 LOG_DEBUG("spells.aura", "Effect: StealBeneficialBuff");
5569
5570 if (!unitTarget || unitTarget == m_caster) // can't steal from self
5571 return;
5572
5573 DispelChargesList steal_list;
5574
5575 // Create dispel mask by dispel type
5576 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[effIndex].MiscValue));
5577 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5578 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5579 {
5580 Aura* aura = itr->second;
5582 if (!aurApp)
5583 continue;
5584
5585 if ((aura->GetSpellInfo()->GetDispelMask()) & dispelMask)
5586 {
5587 // Need check for passive? this
5588 if (!aurApp->IsPositive() || aura->IsPassive() || aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_CANNOT_BE_STOLEN))
5589 continue;
5590
5591 // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
5592 // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
5593 // Polymorph instead of 1 / (5 + 1) -> 16%.
5594 bool dispel_charges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_REMOVES_CHARGES);
5595 uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
5596 if (charges > 0)
5597 steal_list.push_back(std::make_pair(aura, charges));
5598 }
5599 }
5600
5601 if (steal_list.empty())
5602 return;
5603
5604 // Ok if exist some buffs for dispel try dispel it
5605 uint32 failCount = 0;
5606 DispelList success_list;
5607 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
5608 // dispel N = damage buffs (or while exist buffs for dispel)
5609 for (int32 count = 0; count < damage && !steal_list.empty();)
5610 {
5611 // Random select buff for dispel
5612 DispelChargesList::iterator itr = steal_list.begin();
5613 std::advance(itr, urand(0, steal_list.size() - 1));
5614
5615 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
5616 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
5617 if (!chance)
5618 {
5619 steal_list.erase(itr);
5620 continue;
5621 }
5622 else
5623 {
5624 if (roll_chance_i(chance))
5625 {
5626 success_list.push_back(std::make_pair(itr->first->GetId(), itr->first->GetCasterGUID()));
5627 --itr->second;
5628 if (itr->second <= 0)
5629 steal_list.erase(itr);
5630 }
5631 else
5632 {
5633 if (!failCount)
5634 {
5635 // Failed to dispell
5636 dataFail << m_caster->GetGUID(); // Caster GUID
5637 dataFail << unitTarget->GetGUID(); // Victim GUID
5638 dataFail << uint32(m_spellInfo->Id); // dispel spell id
5639 }
5640 ++failCount;
5641 dataFail << uint32(itr->first->GetId()); // Spell Id
5642 }
5643 ++count;
5644 }
5645 }
5646
5647 if (failCount)
5648 m_caster->SendMessageToSet(&dataFail, true);
5649
5650 if (success_list.empty())
5651 return;
5652
5653 WorldPacket dataSuccess(SMSG_SPELLSTEALLOG, 8 + 8 + 4 + 1 + 4 + damage * 5);
5654 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
5655 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
5656 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
5657 dataSuccess << uint8(0); // not used
5658 dataSuccess << uint32(success_list.size()); // count
5659 for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
5660 {
5661 dataSuccess << uint32(itr->first); // Spell Id
5662 dataSuccess << uint8(0); // 0 - steals !=0 transfers
5663 unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, m_caster);
5664 }
5665 m_caster->SendMessageToSet(&dataSuccess, true);
5666}
std::list< std::pair< uint32, ObjectGuid > > DispelList
Definition: SpellEffects.cpp:2543
@ SPELL_ATTR7_DISPEL_REMOVES_CHARGES
Definition: SharedDefines.h:651
@ SPELL_ATTR4_CANNOT_BE_STOLEN
Definition: SharedDefines.h:536
@ SMSG_SPELLSTEALLOG
Definition: Opcodes.h:849
void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, Unit *stealer)
Definition: Unit.cpp:4962
bool IsPositive() const
Definition: SpellAuras.h:68
uint8 GetCharges() const
Definition: SpellAuras.h:141
bool IsPassive() const
Definition: SpellAuras.cpp:1082

References damage, effectHandleMode, SpellInfo::Effects, Aura::GetApplicationOfTarget(), Aura::GetCharges(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::GetOwnedAuras(), Object::GetPackGUID(), Aura::GetSpellInfo(), Aura::GetStackAmount(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsFriendlyTo(), Aura::IsPassive(), AuraApplication::IsPositive(), LOG_DEBUG, m_caster, m_spellInfo, Unit::RemoveAurasDueToSpellBySteal(), roll_chance_i(), WorldObject::SendMessageToSet(), SMSG_DISPEL_FAILED, SMSG_SPELLSTEALLOG, SPELL_ATTR4_CANNOT_BE_STOLEN, SPELL_ATTR7_DISPEL_REMOVES_CHARGES, SPELL_EFFECT_HANDLE_HIT_TARGET, unitTarget, and urand().

◆ EffectStuck()

void Spell::EffectStuck ( SpellEffIndex  effIndex)
4160{
4162 return;
4163
4165 return;
4166
4167 Player* target = m_caster->ToPlayer();
4168 if (target->IsInFlight())
4169 return;
4170
4171 // xinef: if player is dead - teleport to graveyard
4172 if (!target->IsAlive())
4173 {
4175 return;
4176
4177 // xinef: player is in corpse
4178 if (!target->HasPlayerFlag(PLAYER_FLAGS_GHOST))
4179 target->BuildPlayerRepop();
4180 target->RepopAtGraveyard();
4181 return;
4182 }
4183
4184 // xinef: no hearthstone in bag or on cooldown
4185 Item* hearthStone = target->GetItemByEntry(6948);
4186 if (!hearthStone || target->HasSpellCooldown(8690))
4187 {
4188 float o = rand_norm() * 2 * M_PI;
4189 Position pos = *target;
4190 target->MovePositionToFirstCollision(pos, 5.0f, o);
4191 target->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation());
4192 return;
4193 }
4194
4195 // xinef: we have hearthstone not on cooldown, just use it
4197}
double rand_norm()
Definition: Random.cpp:77
@ PLAYER_FLAGS_GHOST
Definition: Player.h:478
@ SPELL_AURA_PREVENT_RESURRECTION
Definition: SpellAuraDefines.h:377
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
Definition: Object.cpp:2855
void RepopAtGraveyard()
Definition: Player.cpp:4862
void BuildPlayerRepop()
Definition: Player.cpp:4366

References Player::BuildPlayerRepop(), Unit::CastSpell(), effectHandleMode, Player::GetItemByEntry(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Object::GetTypeId(), Unit::HasAuraType(), Player::HasPlayerFlag(), Player::HasSpellCooldown(), Unit::IsAlive(), Unit::IsInFlight(), m_caster, WorldObject::MovePositionToFirstCollision(), Unit::NearTeleportTo(), PLAYER_FLAGS_GHOST, rand_norm(), Player::RepopAtGraveyard(), SPELL_AURA_PREVENT_RESURRECTION, SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD, and TYPEID_PLAYER.

◆ EffectSummonChangeItem()

void Spell::EffectSummonChangeItem ( SpellEffIndex  effIndex)
2181{
2183 return;
2184
2186 return;
2187
2188 Player* player = m_caster->ToPlayer();
2189
2190 // applied only to using item
2191 if (!m_CastItem)
2192 return;
2193
2194 // ... only to item in own inventory/bank/equip_slot
2195 if (m_CastItem->GetOwnerGUID() != player->GetGUID())
2196 return;
2197
2198 uint32 newitemid = m_spellInfo->Effects[effIndex].ItemType;
2199 if (!newitemid)
2200 return;
2201
2202 uint16 pos = m_CastItem->GetPos();
2203
2204 Item* pNewItem = Item::CreateItem(newitemid, 1, player);
2205 if (!pNewItem)
2206 return;
2207
2208 // Client-side enchantment durations update
2210
2214
2216 {
2218 player->DurabilityLoss(pNewItem, lossPercent);
2219 }
2220
2221 if (player->IsInventoryPos(pos))
2222 {
2223 ItemPosCountVec dest;
2224 InventoryResult msg = player->CanStoreItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2225 if (msg == EQUIP_ERR_OK)
2226 {
2227 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2228
2229 // prevent crash at access and unexpected charges counting with item update queue corrupt
2231 m_targets.SetItemTarget(nullptr);
2232
2233 m_CastItem = nullptr;
2235
2236 player->StoreItem(dest, pNewItem, true);
2237 player->ItemAddedQuestCheck(pNewItem->GetEntry(), 1);
2238 return;
2239 }
2240 }
2241 else if (player->IsBankPos(pos))
2242 {
2243 ItemPosCountVec dest;
2244 uint8 msg = player->CanBankItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2245 if (msg == EQUIP_ERR_OK)
2246 {
2247 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2248
2249 // prevent crash at access and unexpected charges counting with item update queue corrupt
2251 m_targets.SetItemTarget(nullptr);
2252
2253 m_CastItem = nullptr;
2255
2256 player->BankItem(dest, pNewItem, true);
2257 return;
2258 }
2259 }
2260 else if (player->IsEquipmentPos(pos))
2261 {
2262 uint16 dest;
2263
2264 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2265
2266 uint8 msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
2267
2268 if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CANT_DO_RIGHT_NOW)
2269 {
2271
2272 // prevent crash at access and unexpected charges counting with item update queue corrupt
2274 m_targets.SetItemTarget(nullptr);
2275
2276 m_CastItem = nullptr;
2278
2279 player->EquipItem(dest, pNewItem, true);
2280 player->AutoUnequipOffhandIfNeed();
2281 return;
2282 }
2283 }
2284
2285 // fail
2286 delete pNewItem;
2287}
@ EQUIP_ERR_CANT_DO_RIGHT_NOW
Definition: Item.h:86
@ ITEM_FIELD_DURABILITY
Definition: UpdateFields.h:69
@ ITEM_FIELD_MAXDURABILITY
Definition: UpdateFields.h:70
uint8 GetSlot() const
Definition: Item.h:278
static Item * CreateItem(uint32 item, uint32 count, Player const *player=nullptr, bool clone=false, uint32 randomPropertyId=0)
Definition: Item.cpp:1088
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition: Item.h:302
uint16 GetPos() const
Definition: Item.h:282
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition: Item.h:303
uint8 GetBagSlot() const
Definition: Item.cpp:785
void Clear()
Definition: ObjectGuid.h:138
static bool IsEquipmentPos(uint16 pos)
Definition: Player.h:1255
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:1828
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition: Player.h:1324
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition: Player.h:1275
void UpdateEnchantmentDurations()
Definition: PlayerStorage.cpp:4749
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2589
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition: PlayerStorage.cpp:3038
static bool IsInventoryPos(uint16 pos)
Definition: Player.h:1253
void AutoUnequipOffhandIfNeed(bool force=false)
Definition: Player.cpp:12415
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2742
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:2047
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition: PlayerQuest.cpp:1829
static bool IsBankPos(uint16 pos)
Definition: Player.h:1258

References Player::AutoUnequipOffhandIfNeed(), Player::BankItem(), Player::CanBankItem(), Player::CanEquipItem(), Player::CanStoreItem(), ObjectGuid::Clear(), Item::CreateItem(), Player::DestroyItem(), Player::DurabilityLoss(), effectHandleMode, SpellInfo::Effects, EQUIP_ERR_CANT_DO_RIGHT_NOW, EQUIP_ERR_OK, Player::EquipItem(), EQUIPMENT_SLOT_MAINHAND, Item::GetBagSlot(), Item::GetEnchantmentCharges(), Item::GetEnchantmentDuration(), Item::GetEnchantmentId(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), Item::GetOwnerGUID(), Item::GetPos(), Item::GetSlot(), Object::GetTypeId(), Object::GetUInt32Value(), Player::IsBankPos(), Player::IsEquipmentPos(), Player::IsInventoryPos(), ITEM_FIELD_DURABILITY, ITEM_FIELD_MAXDURABILITY, Player::ItemAddedQuestCheck(), m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, PERM_ENCHANTMENT_SLOT, Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT, Player::StoreItem(), TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), TYPEID_PLAYER, and Player::UpdateEnchantmentDurations().

◆ EffectSummonCritter()

void Spell::EffectSummonCritter ( SpellEffIndex  effIndex)

◆ EffectSummonObject()

void Spell::EffectSummonObject ( SpellEffIndex  effIndex)
4547{
4549 return;
4550
4551 uint32 gameobjectId = m_spellInfo->Effects[effIndex].MiscValue;
4552
4553 uint8 slot = 0;
4554 switch (m_spellInfo->Effects[effIndex].Effect)
4555 {
4557 slot = 0;
4558 break;
4560 slot = 1;
4561 break;
4563 slot = 2;
4564 break;
4566 slot = 3;
4567 break;
4568 default:
4569 return;
4570 }
4571
4572 if (m_caster)
4573 {
4574 ObjectGuid guid = m_caster->m_ObjectSlot[slot];
4575 if (guid)
4576 {
4577 if (GameObject* gameObject = m_caster->GetMap()->GetGameObject(guid))
4578 {
4579 // Recast case - null spell id to make auras not be removed on object remove from world
4580 if (m_spellInfo->Id == gameObject->GetSpellId())
4581 gameObject->SetSpellId(0);
4582 m_caster->RemoveGameObject(gameObject, true);
4583 }
4584 m_caster->m_ObjectSlot[slot].Clear();
4585 }
4586 }
4587
4588 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobjectId) ? new StaticTransport() : new GameObject();
4589
4590 float x, y, z;
4591 // If dest location if present
4592 if (m_targets.HasDst())
4593 destTarget->GetPosition(x, y, z);
4594 // Summon in random point all other units if location present
4595 else
4597
4598 Map* map = m_caster->GetMap();
4599 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobjectId, map, m_caster->GetPhaseMask(), x, y, z, m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4600 {
4601 delete pGameObj;
4602 return;
4603 }
4604
4605 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
4606 int32 duration = m_spellInfo->GetDuration();
4607 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4608 pGameObj->SetSpellId(m_spellInfo->Id);
4609 m_caster->AddGameObject(pGameObj);
4610
4611 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4612
4613 map->AddToMap(pGameObj, true);
4614
4615 m_caster->m_ObjectSlot[slot] = pGameObj->GetGUID();
4616}
#define DEFAULT_WORLD_OBJECT_SIZE
Definition: ObjectDefines.h:45
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT4
Definition: SharedDefines.h:885
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT1
Definition: SharedDefines.h:882
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT3
Definition: SharedDefines.h:884
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT2
Definition: SharedDefines.h:883
ObjectGuid m_ObjectSlot[MAX_GAMEOBJECT_SLOT]
Definition: Unit.h:1411

References Unit::AddGameObject(), Map::AddToMap(), ObjectGuid::Clear(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Map::GetGameObject(), Object::GetGUID(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, m_caster, Unit::m_ObjectSlot, m_spellInfo, m_targets, Unit::RemoveGameObject(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_SUMMON_OBJECT_SLOT1, SPELL_EFFECT_SUMMON_OBJECT_SLOT2, SPELL_EFFECT_SUMMON_OBJECT_SLOT3, and SPELL_EFFECT_SUMMON_OBJECT_SLOT4.

◆ EffectSummonObjectWild()

void Spell::EffectSummonObjectWild ( SpellEffIndex  effIndex)
3717{
3719 return;
3720
3721 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
3722
3723 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
3724
3725 WorldObject* target = focusObject;
3726 if (!target)
3727 target = m_caster;
3728
3729 float x, y, z;
3730 if (m_targets.HasDst())
3731 destTarget->GetPosition(x, y, z);
3732 else
3734
3735 Map* map = target->GetMap();
3736
3737 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
3738 {
3739 delete pGameObj;
3740 return;
3741 }
3742
3743 int32 duration = m_spellInfo->GetDuration();
3744
3745 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
3746 pGameObj->SetSpellId(m_spellInfo->Id);
3747
3748 ExecuteLogEffectSummonObject(effIndex, pGameObj);
3749
3750 // Wild object not have owner and check clickable by players
3751 map->AddToMap(pGameObj, true);
3752
3753 if (pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP)
3754 if (Player* player = m_caster->ToPlayer())
3755 if (Battleground* bg = player->GetBattleground())
3756 bg->SetDroppedFlagGUID(pGameObj->GetGUID(), player->GetTeamId() == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE);
3757
3758 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
3759 {
3760 linkedTrap->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS :0);
3761 linkedTrap->SetSpellId(m_spellInfo->Id);
3762 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
3763 }
3764}
@ GAMEOBJECT_TYPE_FLAGDROP
Definition: SharedDefines.h:1586
@ TEAM_ALLIANCE
Definition: SharedDefines.h:760
@ TEAM_HORDE
Definition: SharedDefines.h:761
GameObject * GetLinkedTrap()
Definition: GameObject.cpp:2726
GameobjectTypes GetGoType() const
Definition: GameObject.h:204

References Map::AddToMap(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), focusObject, GAMEOBJECT_TYPE_FLAGDROP, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), GameObject::GetGoType(), Object::GetGUID(), GameObject::GetLinkedTrap(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, m_caster, m_spellInfo, m_targets, GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, TEAM_ALLIANCE, TEAM_HORDE, and Object::ToPlayer().

◆ EffectSummonPet()

void Spell::EffectSummonPet ( SpellEffIndex  effIndex)
3119{
3121 return;
3122
3123 if (!m_originalCaster)
3124 return;
3125
3126 uint32 petentry = m_spellInfo->Effects[effIndex].MiscValue;
3127 int32 duration = m_spellInfo->GetDuration();
3128
3129 if(Player* modOwner = m_originalCaster->GetSpellModOwner())
3130 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
3131
3132 Player* owner = m_originalCaster->ToPlayer();
3133 if (!owner && m_originalCaster->ToCreature()->IsTotem())
3135
3136 if (!owner)
3137 {
3138 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(67);
3139 if (properties)
3140 {
3141 // Xinef: unsummon old guardian
3142 if (Guardian* oldPet = m_originalCaster->GetGuardianPet())
3143 oldPet->UnSummon();
3144 SummonGuardian(effIndex, petentry, properties, 1, false);
3145 }
3146 return;
3147 }
3148
3149 Pet* OldSummon = owner->GetPet();
3150
3151 // if pet requested type already exist
3152 if (OldSummon)
3153 {
3154 if (petentry == 0 || OldSummon->GetEntry() == petentry)
3155 {
3156 // pet in corpse state can't be summoned
3157 if (OldSummon->isDead())
3158 return;
3159
3160 ASSERT(OldSummon->GetMap() == owner->GetMap());
3161
3162 //OldSummon->GetMap()->Remove(OldSummon->ToCreature(), false);
3163
3164 float px, py, pz;
3165 owner->GetClosePoint(px, py, pz, OldSummon->GetObjectSize());
3166
3167 OldSummon->NearTeleportTo(px, py, pz, OldSummon->GetOrientation());
3168 OldSummon->UpdateObjectVisibility();
3169
3170 OldSummon->SetHealth(OldSummon->GetMaxHealth());
3171 OldSummon->SetPower(OldSummon->getPowerType(), OldSummon->GetMaxPower(OldSummon->getPowerType()));
3172 // notify player
3173 for (CreatureSpellCooldowns::const_iterator itr = OldSummon->m_CreatureSpellCooldowns.begin(); itr != OldSummon->m_CreatureSpellCooldowns.end(); ++itr)
3174 owner->SendClearCooldown(itr->first, OldSummon);
3175
3176 // actually clear cooldowns
3177 OldSummon->m_CreatureSpellCooldowns.clear();
3178 Unit::AuraApplicationMap& myAuras = OldSummon->GetAppliedAuras();
3179 for (Unit::AuraApplicationMap::iterator i = myAuras.begin(); i != myAuras.end();)
3180 {
3181 Aura const* aura = i->second->GetBase();
3182 if (!aura->IsPassive() && !OldSummon->IsPetAura(aura) && aura->CanBeSentToClient())
3183 OldSummon->RemoveAura(i);
3184 else
3185 ++i;
3186 }
3187 return;
3188 }
3189
3190 if (owner->GetTypeId() == TYPEID_PLAYER)
3191 owner->ToPlayer()->RemovePet(OldSummon, PET_SAVE_NOT_IN_SLOT, false);
3192 else
3193 return;
3194 }
3195
3196 float x, y, z;
3197 owner->GetClosePoint(x, y, z, owner->GetObjectSize());
3198 Pet* pet = owner->SummonPet(petentry, x, y, z, owner->GetOrientation(), SUMMON_PET);
3199 if (!pet)
3200 return;
3201
3202 if (m_caster->GetTypeId() == TYPEID_UNIT)
3203 {
3204 if (m_caster->ToCreature()->IsTotem())
3206 else
3208 }
3209
3211
3212 // Reset cooldowns
3214 {
3215 pet->m_CreatureSpellCooldowns.clear();
3216 owner->PetSpellInitialize();
3217 }
3218
3219 // Set health to max if new pet is summoned
3220 // in this function old pet is saved with current health eg. 20% and new one is loaded from db with same amount
3221 // pet should have full health
3222 pet->SetHealth(pet->GetMaxHealth());
3223
3224 // generate new name for summon pet
3225 std::string new_name = sObjectMgr->GeneratePetName(petentry);
3226 if (!new_name.empty())
3227 pet->SetName(new_name);
3228
3229 // ExecuteLogEffectSummonObject(effectInfo->EffectIndex, pet);
3230}
@ REACT_DEFENSIVE
Definition: Unit.h:549
@ REACT_AGGRESSIVE
Definition: Unit.h:550
@ SPELLMOD_DURATION
Definition: SpellDefines.h:78
void SetReactState(ReactStates st)
Definition: Creature.h:91
CreatureSpellCooldowns m_CreatureSpellCooldowns
Definition: Creature.h:246
Definition: TemporarySummon.h:95
void SetName(std::string const &newname)
Definition: Object.h:450
float GetObjectSize() const
Definition: Object.cpp:2768
void SendClearCooldown(uint32 spell_id, Unit *target)
Definition: Player.cpp:14598
bool IsPetAura(Aura const *aura)
Definition: Unit.cpp:17240
void UpdateObjectVisibility(bool forced=true, bool fromUpdate=false) override
Definition: Unit.cpp:19034
Powers getPowerType() const
Definition: Unit.h:800
bool isDead() const
Definition: Unit.h:1152
bool CanBeSentToClient() const
Definition: SpellAuras.cpp:1137
void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
Definition: SpellEffects.cpp:5932

References ASSERT, Aura::CanBeSentToClient(), CLASS_CONTEXT_PET, CLASS_HUNTER, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetEntry(), Unit::GetGuardianPet(), WorldObject::GetMap(), Unit::GetMaxHealth(), Unit::GetMaxPower(), WorldObject::GetObjectSize(), Position::GetOrientation(), Player::GetPet(), Unit::getPowerType(), Unit::GetSpellModOwner(), Object::GetTypeId(), SpellInfo::Id, Player::IsClass(), Unit::isDead(), Aura::IsPassive(), Unit::IsPetAura(), Unit::IsTotem(), m_caster, Creature::m_CreatureSpellCooldowns, m_originalCaster, m_spellInfo, Unit::NearTeleportTo(), PET_SAVE_NOT_IN_SLOT, Player::PetSpellInitialize(), REACT_AGGRESSIVE, REACT_DEFENSIVE, Unit::RemoveAura(), Player::RemovePet(), Player::SendClearCooldown(), Unit::SetHealth(), WorldObject::SetName(), Unit::SetPower(), Creature::SetReactState(), Unit::SetUInt32Value(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, SPELLMOD_DURATION, sSummonPropertiesStore, SUMMON_PET, SummonGuardian(), Player::SummonPet(), Object::ToCreature(), Object::ToPlayer(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_CREATED_BY_SPELL, and Unit::UpdateObjectVisibility().

◆ EffectSummonPlayer()

void Spell::EffectSummonPlayer ( SpellEffIndex  effIndex)
4200{
4201 // workaround - this effect should not use target map
4203 return;
4204
4205 if (!unitTarget)
4206 return;
4207
4208 Player* player = unitTarget->ToPlayer();
4209 if (!player)
4210 {
4211 return;
4212 }
4213
4214 // Evil Twin (ignore player summon, but hide this for summoner)
4215 // Xinef: Unit Target may be on other map!!!, Need workaround
4216 if (unitTarget->HasAura(23445))
4217 return;
4218
4219 float x, y, z;
4220 m_caster->GetPosition(x, y, z);
4221
4222 player->SetSummonPoint(m_caster->GetMapId(), x, y, z);
4223
4224 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
4225 data << m_caster->GetGUID(); // summoner guid
4226 data << uint32(m_caster->GetZoneId()); // summoner zone
4227 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
4228 player->GetSession()->SendPacket(&data);
4229}
#define MAX_PLAYER_SUMMON_DELAY
Definition: Player.h:928
@ SMSG_SUMMON_REQUEST
Definition: Opcodes.h:713
void SetSummonPoint(uint32 mapid, float x, float y, float z, uint32 delay=0, bool asSpectator=false)
Definition: Player.cpp:16266

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), Player::GetSession(), WorldObject::GetZoneId(), Unit::HasAura(), IN_MILLISECONDS, m_caster, MAX_PLAYER_SUMMON_DELAY, WorldSession::SendPacket(), Player::SetSummonPoint(), SMSG_SUMMON_REQUEST, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSummonRaFFriend()

void Spell::EffectSummonRaFFriend ( SpellEffIndex  effIndex)
6318{
6320 return;
6321
6323 return;
6324
6325 if (!unitTarget)
6326 return;
6327
6328 Player* player = unitTarget->ToPlayer();
6329 if (!player)
6330 {
6331 return;
6332 }
6333
6334 float x, y, z;
6335 m_caster->GetPosition(x, y, z);
6337 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
6338 data << m_caster->GetGUID();
6339 data << uint32(m_caster->GetZoneId());
6340 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
6341 player->GetSession()->SendPacket(&data);
6342}

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), Player::GetSession(), Object::GetTypeId(), WorldObject::GetZoneId(), IN_MILLISECONDS, m_caster, MAX_PLAYER_SUMMON_DELAY, WorldSession::SendPacket(), Player::SetSummonPoint(), SMSG_SUMMON_REQUEST, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectSummonType()

void Spell::EffectSummonType ( SpellEffIndex  effIndex)
2312{
2314 return;
2315
2316 uint32 entry = m_spellInfo->Effects[effIndex].MiscValue;
2317 if (!entry)
2318 return;
2319
2320 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[effIndex].MiscValueB);
2321 if (!properties)
2322 {
2323 LOG_ERROR("spells.effect", "EffectSummonType: Unhandled summon type {}", m_spellInfo->Effects[effIndex].MiscValueB);
2324 return;
2325 }
2326
2327 if (!m_originalCaster)
2328 return;
2329
2330 bool personalSpawn = (properties->Flags & SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER) != 0;
2331 int32 duration = m_spellInfo->GetDuration();
2332 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
2333 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
2334
2335 TempSummon* summon = nullptr;
2336
2337 // determine how many units should be summoned
2338 uint32 numSummons;
2339
2340 // some spells need to summon many units, for those spells number of summons is stored in effect value
2341 // however so far noone found a generic check to find all of those (there's no related data in summonproperties.dbc
2342 // and in spell attributes, possibly we need to add a table for those)
2343 // so here's a list of MiscValueB values, which is currently most generic check
2344 switch (properties->Id)
2345 {
2346 case 64:
2347 case 61:
2348 case 1101:
2349 case 66:
2350 case 648:
2351 case 2301:
2352 case 1061:
2353 case 1261:
2354 case 629:
2355 case 181:
2356 case 715:
2357 case 1562:
2358 case 833:
2359 case 1161:
2360 case 713: // xinef, bloodworms
2361 numSummons = (damage > 0) ? damage : 1;
2362 break;
2363 default:
2364 numSummons = 1;
2365 break;
2366 }
2367
2368 switch (properties->Category)
2369 {
2373 if (properties->Flags & 512)
2374 {
2375 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2376 break;
2377 }
2378 switch (properties->Type)
2379 {
2380 case SUMMON_TYPE_PET:
2383 case SUMMON_TYPE_MINION:
2384 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2385 break;
2386 // Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE)
2389 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2390 break;
2392 case SUMMON_TYPE_TOTEM:
2393 {
2394 // protection code
2395 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2396 if (!summon || !summon->IsTotem())
2397 return;
2398
2399 // Mana Tide Totem
2400 if (m_spellInfo->Id == 16190)
2402
2403 if (damage && properties->Type != SUMMON_TYPE_LIGHTWELL) // Health set in script for lightwell
2404 {
2405 summon->SetMaxHealth(damage);
2406 summon->SetHealth(damage);
2407 }
2408 break;
2409 }
2410 case SUMMON_TYPE_JEEVES:
2412 {
2413 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2414 if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION))
2415 return;
2416
2417 summon->SelectLevel(); // some summoned creaters have different from 1 DB data for level/hp
2419
2420 summon->SetImmuneToAll(true);
2422
2423 // Xinef: Pet can have some auras in creature_addon or in scripts, do not remove them instantly
2424 //summon->AI()->EnterEvadeMode();
2425 if (properties->Type != SUMMON_TYPE_JEEVES)
2426 {
2427 summon->GetMotionMaster()->Clear(false);
2429 }
2430 break;
2431 }
2432 default:
2433 {
2434 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2435
2436 TempSummonType summonType = (duration <= 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
2437
2438 for (uint32 count = 0; count < numSummons; ++count)
2439 {
2440 Position pos;
2441 if (count == 0)
2442 pos = *destTarget;
2443 else
2444 // randomize position for multiple summons
2445 pos = m_caster->GetRandomPoint(*destTarget, radius);
2446
2447 summon = m_originalCaster->SummonCreature(entry, pos, summonType, duration, 0, nullptr, personalSpawn);
2448 if (!summon)
2449 continue;
2450
2451 summon->SetTempSummonType(summonType);
2452
2453 if (properties->Category == SUMMON_CATEGORY_ALLY)
2454 {
2457 }
2458
2459 ExecuteLogEffectSummonObject(effIndex, summon);
2460 }
2461 return;
2462 }
2463 }//switch
2464 break;
2466 // Xinef: SummonGuardian function can summon a few npcs of same type, remove old summons with same entry here
2467 if (m_originalCaster)
2469 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2470 break;
2472 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2473 break;
2475 // Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
2476 // to cast a ride vehicle spell on the summoned unit.
2477 //float x, y, z;
2478 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
2479 // xinef: vehicles summoned in air, eg. Cold Hearted quest
2480 if (std::fabs(m_caster->GetPositionZ() - destTarget->GetPositionZ()) > 6.0f)
2482
2483 summon = m_originalCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_caster, m_spellInfo->Id, 0, personalSpawn);
2484 if (!summon || !summon->IsVehicle())
2485 return;
2486
2487 // The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
2489 int32 basePoints = m_spellInfo->Effects[effIndex].CalcValue();
2490 if (basePoints > 1) // xinef: some summoning spells have value 1 - indicates vehicle seat
2491 {
2492 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(basePoints);
2493 if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
2494 spellId = spellInfo->Id;
2495 }
2496
2497 // xinef: if we have small value, it indicates seat position
2498 if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS)
2499 m_originalCaster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, basePoints, summon, true);
2500 else
2501 m_originalCaster->CastSpell(summon, spellId, true);
2502
2503 // xinef: i think this is wrong, found only 2 vehicles with faction override and one of them should inherit caster faction...
2504 //uint32 faction = properties->Faction;
2505 //if (!faction)
2506 uint32 faction = m_originalCaster->GetFaction();
2507
2508 summon->SetFaction(faction);
2509 break;
2510 }
2511
2512 if (summon)
2513 {
2515 ExecuteLogEffectSummonObject(effIndex, summon);
2516 }
2517}
TempSummonType
Definition: Object.h:44
@ TEMPSUMMON_DEAD_DESPAWN
Definition: Object.h:51
@ REACT_PASSIVE
Definition: Unit.h:548
@ UNIT_MASK_MINION
Definition: UnitDefines.h:136
NPCFlags
Non Player Character flags.
Definition: UnitDefines.h:292
@ VEHICLE_SPELL_RIDE_HARDCODED
Definition: VehicleDefines.h:52
@ MOTION_SLOT_ACTIVE
Definition: MotionMaster.h:62
@ SPELL_AURA_CONTROL_VEHICLE
Definition: SpellAuraDefines.h:299
@ SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER
Definition: DBCEnums.h:428
#define MAX_VEHICLE_SEATS
Definition: DBCStructure.h:2024
@ SUMMON_TYPE_VEHICLE2
Definition: SharedDefines.h:3304
@ SUMMON_TYPE_LIGHTWELL
Definition: SharedDefines.h:3305
@ SUMMON_TYPE_MINION
Definition: SharedDefines.h:3297
@ SUMMON_TYPE_GUARDIAN
Definition: SharedDefines.h:3296
@ SUMMON_TYPE_JEEVES
Definition: SharedDefines.h:3306
@ SUMMON_TYPE_PET
Definition: SharedDefines.h:3295
@ SUMMON_TYPE_TOTEM
Definition: SharedDefines.h:3298
@ SUMMON_TYPE_VEHICLE
Definition: SharedDefines.h:3303
@ SUMMON_TYPE_MINIPET
Definition: SharedDefines.h:3299
@ SUMMON_TYPE_GUARDIAN2
Definition: SharedDefines.h:3300
@ SUMMON_CATEGORY_VEHICLE
Definition: SharedDefines.h:3287
@ SUMMON_CATEGORY_ALLY
Definition: SharedDefines.h:3284
@ SUMMON_CATEGORY_WILD
Definition: SharedDefines.h:3283
@ SUMMON_CATEGORY_UNK
Definition: SharedDefines.h:3288
void SelectLevel(bool changelevel=true)
Definition: Creature.cpp:1503
uint32 npcflag
Definition: CreatureData.h:202
void SetTempSummonType(TempSummonType type)
Definition: TemporarySummon.cpp:277
void GetRandomPoint(const Position &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const
Definition: Object.cpp:1502
void SetFaction(uint32 faction)
Definition: Unit.cpp:9992
virtual float GetFollowAngle() const
Definition: Unit.h:1734
void SetOwnerGUID(ObjectGuid owner)
Definition: Unit.cpp:10500
uint32 HasUnitTypeMask(uint32 mask) const
Definition: Unit.h:747
void SetMaxHealth(uint32 val)
Definition: Unit.cpp:15442
void SetCreatorGUID(ObjectGuid creator)
Definition: Unit.h:1159
void ReplaceAllNpcFlags(NPCFlags flags)
Definition: Unit.h:993
void RemoveAllMinionsByEntry(uint32 entry)
Definition: Unit.cpp:10785
void SetImmuneToAll(bool apply, bool keepCombat=false)
Definition: Unit.h:1021
TempSummon * SummonCreature(uint32 entry, Position const &pos, SummonPropertiesEntry const *properties=nullptr, uint32 duration=0, WorldObject *summoner=nullptr, uint32 spellId=0, uint32 vehId=0, bool visibleBySummonerOnly=false)
Definition: Object.cpp:2163
void MoveFollow(Unit *target, float dist, float angle, MovementSlot slot=MOTION_SLOT_ACTIVE, bool inheritWalkState=true)
Definition: MotionMaster.cpp:394
void Clear(bool reset=true)
Definition: MotionMaster.h:165
uint32 Flags
Definition: DBCStructure.h:1915
uint32 Type
Definition: DBCStructure.h:1913
uint32 Id
Definition: DBCStructure.h:1910

References Unit::CastCustomSpell(), Unit::CastSpell(), SummonPropertiesEntry::Category, MotionMaster::Clear(), Unit::CountPctFromMaxHealth(), damage, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), SummonPropertiesEntry::Flags, Creature::GetCreatureTemplate(), SpellInfo::GetDuration(), Unit::GetFaction(), Unit::GetFollowAngle(), Object::GetGUID(), WorldObject::GetMap(), Unit::GetMotionMaster(), Position::GetPositionZ(), WorldObject::GetRandomPoint(), Unit::GetSpellModOwner(), SpellInfo::HasAura(), Unit::HasUnitTypeMask(), SpellInfo::Id, SummonPropertiesEntry::Id, Unit::IsTotem(), Unit::IsVehicle(), LOG_ERROR, m_caster, m_originalCaster, Position::m_positionZ, m_spellInfo, MAX_VEHICLE_SEATS, MOTION_SLOT_ACTIVE, MotionMaster::MoveFollow(), CreatureTemplate::npcflag, PET_FOLLOW_DIST, REACT_PASSIVE, Unit::RemoveAllMinionsByEntry(), Unit::ReplaceAllNpcFlags(), Creature::SelectLevel(), Unit::SetCreatorGUID(), Unit::SetFaction(), Unit::SetHealth(), Unit::SetImmuneToAll(), Unit::SetMaxHealth(), Unit::SetOwnerGUID(), Creature::SetReactState(), TempSummon::SetTempSummonType(), SPELL_AURA_CONTROL_VEHICLE, SPELL_EFFECT_HANDLE_HIT, SPELLMOD_DURATION, SPELLVALUE_BASE_POINT0, sSpellMgr, sSummonPropertiesStore, SUMMON_CATEGORY_ALLY, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, SUMMON_CATEGORY_UNK, SUMMON_CATEGORY_VEHICLE, SUMMON_CATEGORY_WILD, SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER, SUMMON_TYPE_GUARDIAN, SUMMON_TYPE_GUARDIAN2, SUMMON_TYPE_JEEVES, SUMMON_TYPE_LIGHTWELL, SUMMON_TYPE_MINION, SUMMON_TYPE_MINIPET, SUMMON_TYPE_PET, SUMMON_TYPE_TOTEM, SUMMON_TYPE_VEHICLE, SUMMON_TYPE_VEHICLE2, Map::SummonCreature(), WorldObject::SummonCreature(), SummonGuardian(), TEMPSUMMON_DEAD_DESPAWN, TEMPSUMMON_TIMED_DESPAWN, SummonPropertiesEntry::Type, UNIT_MASK_MINION, and VEHICLE_SPELL_RIDE_HARDCODED.

◆ EffectTameCreature()

void Spell::EffectTameCreature ( SpellEffIndex  effIndex)
3063{
3065 return;
3066
3067 if (m_caster->GetPetGUID())
3068 return;
3069
3070 if (!unitTarget)
3071 return;
3072
3074 return;
3075
3076 Creature* creatureTarget = unitTarget->ToCreature();
3077
3078 if (creatureTarget->IsPet())
3079 return;
3080
3082 return;
3083
3084 // cast finish successfully
3085 //SendChannelUpdate(0);
3086 finish();
3087
3088 Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
3089 if (!pet) // in very specific state like near world end/etc.
3090 return;
3091
3092 // "kill" original creature
3093 creatureTarget->DespawnOrUnsummon();
3094
3095 uint8 level = (creatureTarget->GetLevel() < (m_caster->GetLevel() - 5)) ? (m_caster->GetLevel() - 5) : creatureTarget->GetLevel();
3096
3097 // prepare visual effect for levelup
3098 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
3099
3100 // add to world
3101 pet->GetMap()->AddToMap(pet->ToCreature(), true);
3102
3103 // visual effect for levelup
3104 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
3105
3106 // caster have pet now
3107 m_caster->SetMinion(pet, true);
3108
3109 pet->InitTalentForLevel();
3110
3112 {
3115 }
3116}
@ UNIT_FIELD_LEVEL
Definition: UpdateFields.h:114

References Map::AddToMap(), CLASS_CONTEXT_PET, CLASS_HUNTER, Unit::CreateTamedPetFrom(), Creature::DespawnOrUnsummon(), effectHandleMode, finish(), Unit::GetLevel(), WorldObject::GetMap(), Unit::GetPetGUID(), Object::GetTypeId(), SpellInfo::Id, Pet::InitTalentForLevel(), Unit::IsClass(), Unit::IsPet(), m_caster, m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), Unit::SetMinion(), Unit::SetUInt32Value(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_FIELD_LEVEL, and unitTarget.

◆ EffectTaunt()

void Spell::EffectTaunt ( SpellEffIndex  effIndex)
3259{
3261 return;
3262
3263 if (!unitTarget)
3264 return;
3265
3266 // xinef: Hand of Reckoning, cast before checing canhavethreatlist. fixes damage against pets
3267 if (m_spellInfo->Id == 62124 && unitTarget->GetVictim() != m_caster)
3268 {
3269 m_caster->CastSpell(unitTarget, 67485, true);
3271 }
3272
3273 // this effect use before aura Taunt apply for prevent taunt already attacking target
3274 // for spell as marked "non effective at already attacking target"
3276 {
3278 return;
3279 }
3280
3282 {
3283 // Also use this effect to set the taunter's threat to the taunted creature's highest value
3284 float myThreat = unitTarget->GetThreatMgr().GetThreat(m_caster);
3286 if (topThreat > myThreat)
3287 unitTarget->GetThreatMgr().DoAddThreat(m_caster, topThreat - myThreat);
3288
3289 //Set aggro victim to caster
3291 unitTarget->GetThreatMgr().setCurrentVictim(forcedVictim);
3292 }
3293}
@ SPELL_AURA_MOD_TAUNT
Definition: SpellAuraDefines.h:74
Definition: ThreatMgr.h:49
float GetThreat() const
Definition: ThreatMgr.h:63
HostileReference * getMostHated() const
Definition: ThreatMgr.h:169
HostileReference * getReferenceByTarget(Unit const *victim) const
Definition: ThreatMgr.cpp:261
bool empty() const
Definition: ThreatMgr.h:164
void setCurrentVictim(HostileReference *hostileRef)
Definition: ThreatMgr.cpp:572
void DoAddThreat(Unit *victim, float threat)
Definition: ThreatMgr.cpp:453
float GetThreat(Unit *victim, bool alsoSearchOfflineList=false)
Definition: ThreatMgr.cpp:525
ThreatContainer & GetOnlineContainer()
Definition: ThreatMgr.h:276
bool CanHaveThreatList() const
Definition: Unit.cpp:14528

References Unit::CanHaveThreatList(), Unit::CastSpell(), Unit::CombatStart(), ThreatMgr::DoAddThreat(), effectHandleMode, ThreatContainer::empty(), ThreatContainer::getMostHated(), ThreatMgr::GetOnlineContainer(), ThreatContainer::getReferenceByTarget(), HostileReference::GetThreat(), ThreatMgr::GetThreat(), Unit::GetThreatMgr(), Unit::GetVictim(), SpellInfo::HasAura(), SpellInfo::Id, m_caster, m_spellInfo, SendCastResult(), ThreatMgr::setCurrentVictim(), SPELL_AURA_MOD_TAUNT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_DONT_REPORT, and unitTarget.

◆ EffectTeleportUnits()

void Spell::EffectTeleportUnits ( SpellEffIndex  effIndex)
1169{
1171 return;
1172
1173 if (!unitTarget || unitTarget->IsInFlight())
1174 return;
1175
1177 {
1178 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
1179 }
1180
1181 // Pre effects
1182 switch (m_spellInfo->Id)
1183 {
1184 case 70746: // Teleport Into Sunwell (for Battered Hilt)
1185 if (Player* target = unitTarget->ToPlayer())
1186 {
1187 uint32 mapid = destTarget->GetMapId();
1188 float x, y, z, orientation;
1189 destTarget->GetPosition(x, y, z, orientation);
1190 target->TeleportTo(mapid, x, y, z, orientation, TELE_TO_GM_MODE); // skip PlayerCannotEnter check
1191 }
1192 return;
1193 }
1194
1195 // If not exist data for dest location - return
1196 if (!m_targets.HasDst())
1197 {
1198 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - does not have destination for spell ID {}\n", m_spellInfo->Id);
1199 return;
1200 }
1201
1202 // Init dest coordinates
1203 uint32 mapid = destTarget->GetMapId();
1204 if (mapid == MAPID_INVALID)
1205 mapid = unitTarget->GetMapId();
1206 float x, y, z, orientation;
1207 destTarget->GetPosition(x, y, z, orientation);
1208 if (!orientation && m_targets.GetUnitTarget())
1209 orientation = m_targets.GetUnitTarget()->GetOrientation();
1210 LOG_DEBUG("spells.aura", "Spell::EffectTeleportUnits - teleport unit to {} {} {} {} {}\n", mapid, x, y, z, orientation);
1211
1212 if (mapid == unitTarget->GetMapId())
1213 {
1214 if (unitTarget->GetVehicleKit()) // we are vehicle!
1215 unitTarget->GetVehicleKit()->TeleportVehicle(x, y, z, orientation);
1216 else
1217 {
1219 unitTarget->NearTeleportTo(x, y, z, orientation, unitTarget == m_caster, false, withPet, true);
1220 if (unitTarget->GetTypeId() == TYPEID_PLAYER) // pussywizard: for units it's done inside NearTeleportTo
1222 }
1223 }
1224 else if (unitTarget->GetTypeId() == TYPEID_PLAYER)
1225 unitTarget->ToPlayer()->TeleportTo(mapid, x, y, z, orientation, unitTarget == m_caster ? TELE_TO_SPELL : 0);
1226 else
1227 {
1228 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - spellId {} attempted to teleport creature to a different map.", m_spellInfo->Id);
1229 return;
1230 }
1231
1232 // post effects for TARGET_DEST_DB
1233 switch (m_spellInfo->Id)
1234 {
1235 // Dimensional Ripper - Everlook
1236 case 23442:
1237 {
1238 int32 r = irand(0, 119);
1239 if (r >= 70) // 7/12 success
1240 {
1241 if (r < 100) // 4/12 evil twin
1242 m_caster->CastSpell(m_caster, 23445, true);
1243 else // 1/12 fire
1244 m_caster->CastSpell(m_caster, 23449, true);
1245 }
1246 return;
1247 }
1248 // Ultrasafe Transporter: Toshley's Station
1249 case 36941:
1250 {
1251 if (roll_chance_i(50)) // 50% success
1252 {
1253 int32 rand_eff = urand(1, 7);
1254 switch (rand_eff)
1255 {
1256 case 1:
1257 // soul split - evil
1258 m_caster->CastSpell(m_caster, 36900, true);
1259 break;
1260 case 2:
1261 // soul split - good
1262 m_caster->CastSpell(m_caster, 36901, true);
1263 break;
1264 case 3:
1265 // Increase the size
1266 m_caster->CastSpell(m_caster, 36895, true);
1267 break;
1268 case 4:
1269 // Decrease the size
1270 m_caster->CastSpell(m_caster, 36893, true);
1271 break;
1272 case 5:
1273 // Transform
1274 {
1276 m_caster->CastSpell(m_caster, 36897, true);
1277 else
1278 m_caster->CastSpell(m_caster, 36899, true);
1279 break;
1280 }
1281 case 6:
1282 // chicken
1283 m_caster->CastSpell(m_caster, 36940, true);
1284 break;
1285 case 7:
1286 // evil twin
1287 m_caster->CastSpell(m_caster, 23445, true);
1288 break;
1289 }
1290 }
1291 return;
1292 }
1293 }
1294}
#define MAPID_INVALID
Definition: Position.h:248
@ TELE_TO_SPELL
Definition: Player.h:825
@ TELE_TO_GM_MODE
Definition: Player.h:821
TeamId GetTeamId(bool original=false) const
Definition: Player.h:2084
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0, Unit *target=nullptr, bool newInstance=false)
Definition: Player.cpp:1329
Vehicle * GetVehicleKit() const
Definition: Unit.h:1695
void TeleportVehicle(float x, float y, float z, float ang)
Definition: Vehicle.cpp:545

References Unit::CastSpell(), destTarget, effectHandleMode, Position::GetExactDist(), WorldObject::GetMap(), WorldLocation::GetMapId(), Position::GetOrientation(), Position::GetPosition(), Player::GetTeamId(), Object::GetTypeId(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicleKit(), SpellCastTargets::HasDst(), SpellInfo::Id, irand(), Map::IsDungeon(), Unit::IsInFlight(), LOG_DEBUG, LOG_ERROR, m_caster, m_spellInfo, m_targets, MAPID_INVALID, Unit::NearTeleportTo(), roll_chance_i(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SpellInfo::SpellFamilyName, sScriptMgr, TEAM_ALLIANCE, TELE_TO_GM_MODE, TELE_TO_SPELL, Player::TeleportTo(), Vehicle::TeleportVehicle(), Object::ToPlayer(), TYPEID_PLAYER, unitTarget, Unit::UpdateObjectVisibility(), and urand().

◆ EffectTeleUnitsFaceCaster()

◆ EffectThreat()

void Spell::EffectThreat ( SpellEffIndex  effIndex)
3648{
3650 return;
3651
3652 if (!unitTarget || !unitTarget->IsAlive() || !m_caster->IsAlive())
3653 return;
3654
3655 // xinef: skip if target cannot have threat list or caster is friendly (ghoul leap)
3657 return;
3658
3660}
void AddThreat(Unit *victim, float fThreat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell=nullptr)
Definition: Unit.cpp:14567

References Unit::AddThreat(), Unit::CanHaveThreatList(), damage, effectHandleMode, Unit::IsAlive(), Unit::IsFriendlyTo(), m_caster, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectTitanGrip()

void Spell::EffectTitanGrip ( SpellEffIndex  effIndex)
5866{
5868 return;
5869
5871 {
5872 if (Aura* aur = m_caster->GetAura(49152))
5873 aur->RecalculateAmountOfEffects();
5874 else
5875 m_caster->CastSpell(unitTarget, 49152, true); // damage reduction
5876
5878 }
5879}
void SetCanTitanGrip(bool value)
Definition: Player.cpp:13090

References Unit::CastSpell(), effectHandleMode, Unit::GetAura(), Object::GetTypeId(), m_caster, Player::SetCanTitanGrip(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectTradeSkill()

void Spell::EffectTradeSkill ( SpellEffIndex  effIndex)
2800{
2802 return;
2803
2805 return;
2806 // uint32 skillid = m_spellInfo->Effects[i].MiscValue;
2807 // uint16 skillmax = unitTarget->ToPlayer()->(skillid);
2808 // m_caster->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75);
2809}

References effectHandleMode, Object::GetTypeId(), m_caster, SPELL_EFFECT_HANDLE_HIT, and TYPEID_PLAYER.

◆ EffectTransmitted()

void Spell::EffectTransmitted ( SpellEffIndex  effIndex)
5340{
5342 return;
5343
5344 uint32 name_id = m_spellInfo->Effects[effIndex].MiscValue;
5345
5346 GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id);
5347
5348 if (!goinfo)
5349 {
5350 LOG_ERROR("sql.sql", "Gameobject (Entry: {}) not exist and not created at spell (ID: {}) cast", name_id, m_spellInfo->Id);
5351 return;
5352 }
5353
5354 float fx, fy, fz;
5355
5356 if (m_targets.HasDst())
5357 destTarget->GetPosition(fx, fy, fz);
5358 //FIXME: this can be better check for most objects but still hack
5359 else if (m_spellInfo->Effects[effIndex].HasRadius() && m_spellInfo->Speed == 0)
5360 {
5361 float dis = m_spellInfo->Effects[effIndex].CalcRadius(m_originalCaster);
5363 }
5364 else
5365 {
5366 //GO is always friendly to it's creator, get range for friends
5367 float min_dis = m_spellInfo->GetMinRange(true);
5368 float max_dis = m_spellInfo->GetMaxRange(true);
5369 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
5370
5372 }
5373
5374 // Seaforium charge
5375 if (m_spellInfo->Id == 52410 || m_spellInfo->Id == 66268 || m_spellInfo->Id == 66674) // SotA / IoC / IoC Huge
5376 {
5377 fx = m_caster->GetPositionX();
5378 fy = m_caster->GetPositionY();
5379 fz = m_caster->GetPositionZ();
5380 }
5381
5382 Map* cMap = m_caster->GetMap();
5383
5384 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(name_id) ? new StaticTransport() : new GameObject();
5385
5386 if (!pGameObj->Create(cMap->GenerateLowGuid<HighGuid::GameObject>(), name_id, cMap, m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
5387 {
5388 delete pGameObj;
5389 return;
5390 }
5391
5392 int32 duration = m_spellInfo->GetDuration();
5393
5394 switch (goinfo->type)
5395 {
5397 {
5399 m_caster->AddGameObject(pGameObj); // will removed at spell cancel
5400
5401 // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo))
5402 // start time == fish-FISHING_BOBBER_READY_TIME (0..GetDuration(m_spellInfo)-FISHING_BOBBER_READY_TIME)
5403 int32 lastSec = 0;
5404 switch (urand(0, 2))
5405 {
5406 case 0:
5407 lastSec = 3;
5408 break;
5409 case 1:
5410 lastSec = 7;
5411 break;
5412 case 2:
5413 lastSec = 13;
5414 break;
5415 }
5416
5417 // Duration of the fishing bobber can't be higher than the Fishing channeling duration
5418 duration = std::min(duration, duration - lastSec*IN_MILLISECONDS + FISHING_BOBBER_READY_TIME*IN_MILLISECONDS);
5419
5420 break;
5421 }
5423 {
5425 {
5426 pGameObj->AddUniqueUse(m_caster->ToPlayer());
5427 m_caster->AddGameObject(pGameObj); // will be removed at spell cancel
5428 }
5429 break;
5430 }
5431 case GAMEOBJECT_TYPE_DUEL_ARBITER: // 52991
5432 m_caster->AddGameObject(pGameObj);
5433 break;
5436 default:
5437 break;
5438 }
5439
5440 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5441
5442 pGameObj->SetOwnerGUID(m_caster->GetGUID());
5443
5444 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
5445 pGameObj->SetSpellId(m_spellInfo->Id);
5446
5447 ExecuteLogEffectSummonObject(effIndex, pGameObj);
5448
5449 LOG_DEBUG("spells.effect", "AddObject at SpellEfects.cpp EffectTransmitted");
5450 //m_caster->AddGameObject(pGameObj);
5451 //m_ObjToDel.push_back(pGameObj);
5452
5453 cMap->AddToMap(pGameObj, true);
5454
5455 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
5456 {
5457 linkedTrap->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5458 linkedTrap->SetSpellId(m_spellInfo->Id);
5459 linkedTrap->SetOwnerGUID(m_caster->GetGUID());
5460
5461 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
5462 }
5463
5464 if (Player* player = m_caster->ToPlayer())
5465 {
5466 player->SetCanTeleport(true);
5467 }
5468}
#define FISHING_BOBBER_READY_TIME
Definition: GameObject.h:118
@ UNIT_FIELD_CHANNEL_OBJECT
Definition: UpdateFields.h:93
@ GAMEOBJECT_TYPE_DUEL_ARBITER
Definition: SharedDefines.h:1576
@ GAMEOBJECT_TYPE_SUMMONING_RITUAL
Definition: SharedDefines.h:1578
@ GAMEOBJECT_TYPE_CHEST
Definition: SharedDefines.h:1563
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition: SharedDefines.h:1585
@ GAMEOBJECT_TYPE_FISHINGNODE
Definition: SharedDefines.h:1577
void SetOwnerGUID(ObjectGuid owner)
Definition: GameObject.h:164
void AddUniqueUse(Player *player)
Definition: GameObject.cpp:927
float GetMinRange(bool positive=false) const
Definition: SpellInfo.cpp:2313

References Unit::AddGameObject(), Map::AddToMap(), GameObject::AddUniqueUse(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), FISHING_BOBBER_READY_TIME, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DUEL_ARBITER, GAMEOBJECT_TYPE_FISHINGHOLE, GAMEOBJECT_TYPE_FISHINGNODE, GAMEOBJECT_TYPE_SUMMONING_RITUAL, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetGUID(), GameObject::GetLinkedTrap(), WorldObject::GetMap(), SpellInfo::GetMaxRange(), SpellInfo::GetMinRange(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Object::GetTypeId(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, LOG_DEBUG, LOG_ERROR, m_caster, m_originalCaster, m_spellInfo, m_targets, rand_norm(), Object::SetGuidValue(), GameObject::SetOwnerGUID(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SpellInfo::Speed, SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), GameObjectTemplate::type, TYPEID_PLAYER, UNIT_FIELD_CHANNEL_OBJECT, and urand().

◆ EffectTriggerMissileSpell()

void Spell::EffectTriggerMissileSpell ( SpellEffIndex  effIndex)
947{
950 return;
951
952 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
953
954 // normal case
955 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
956 if (!spellInfo)
957 {
958 LOG_DEBUG("spells.aura", "Spell::EffectTriggerMissileSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
959 return;
960 }
961
962 SpellCastTargets targets;
964 {
965 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
966 return;
967 targets.SetUnitTarget(unitTarget);
968 }
969 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
970 {
971 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
972 return;
973
975 targets.SetDst(m_targets);
976
977 targets.SetUnitTarget(m_caster);
978 }
979
980 CustomSpellValues values;
981 // set basepoints for trigger with value effect
983 {
984 // maybe need to set value only when basepoints == 0?
988 }
989
990 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
991 if (m_caster->GetTypeId() == TYPEID_PLAYER && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
992 {
993 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
994 }
995
996 // original caster guid only for GO cast
997 m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, nullptr, nullptr, m_originalCasterGUID);
998}
@ TARGET_FLAG_DEST_LOCATION
Definition: SpellInfo.h:52
@ SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
Definition: SharedDefines.h:926
bool NeedsToBeTriggeredByCaster(SpellInfo const *triggeringSpell, uint8 effIndex=MAX_SPELL_EFFECTS) const
Definition: SpellInfo.cpp:1037
uint32 CategoryRecoveryTime
Definition: SpellInfo.h:349

References CustomSpellValues::AddSpellMod(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), SpellInfo::GetExplicitTargetMask(), Object::GetTypeId(), SpellInfo::Id, LOG_DEBUG, m_caster, m_originalCasterGUID, m_spellInfo, m_targets, SpellInfo::NeedsToBeTriggeredByCaster(), Player::RemoveSpellCooldown(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_UNIT_MASK, Object::ToPlayer(), TRIGGERED_FULL_MASK, TYPEID_PLAYER, and unitTarget.

◆ EffectTriggerRitualOfSummoning()

void Spell::EffectTriggerRitualOfSummoning ( SpellEffIndex  effIndex)
1055{
1057 return;
1058
1059 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1060 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1061
1062 if (!spellInfo)
1063 {
1064 LOG_ERROR("spells.effect", "EffectTriggerRitualOfSummoning of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1065 return;
1066 }
1067
1068 finish();
1069
1070 m_caster->CastSpell((Unit*)nullptr, spellInfo, true);
1071}

References Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, finish(), SpellInfo::Id, LOG_ERROR, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT, and sSpellMgr.

◆ EffectTriggerSpell()

void Spell::EffectTriggerSpell ( SpellEffIndex  effIndex)
Todo:
: move those to spell scripts
790{
793 return;
794
795 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
796
798 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL
800 {
801 // special cases
802 switch (triggered_spell_id)
803 {
804 // Mirror Image
805 case 58832:
806 {
807 // Glyph of Mirror Image
808 if (m_caster->HasAura(63093))
809 m_caster->CastSpell(m_caster, 65047, true); // Mirror Image
810
811 break;
812 }
813 // Demonic Empowerment -- succubus
814 case 54437:
815 {
819
820 // Cast Lesser Invisibility
821 unitTarget->CastSpell(unitTarget, 7870, true);
822 return;
823 }
824 // just skip
825 case 23770: // Sayge's Dark Fortune of *
826 // not exist, common cooldown can be implemented in scripts if need.
827 return;
828 // Brittle Armor - (need add max stack of 24575 Brittle Armor)
829 case 29284:
830 {
831 // Brittle Armor
832 SpellInfo const* spell = sSpellMgr->GetSpellInfo(24575);
833 if (!spell)
834 return;
835
836 for (uint32 j = 0; j < spell->StackAmount; ++j)
837 m_caster->CastSpell(unitTarget, spell->Id, true);
838 return;
839 }
840 // Mercurial Shield - (need add max stack of 26464 Mercurial Shield)
841 case 29286:
842 {
843 // Mercurial Shield
844 SpellInfo const* spell = sSpellMgr->GetSpellInfo(26464);
845 if (!spell)
846 return;
847
848 for (uint32 j = 0; j < spell->StackAmount; ++j)
849 m_caster->CastSpell(unitTarget, spell->Id, true);
850 return;
851 }
852 // Cloak of Shadows
853 case 35729:
854 {
857 for (Unit::AuraApplicationMap::iterator iter = Auras.begin(); iter != Auras.end();)
858 {
859 // remove all harmful spells on you...
860 SpellInfo const* spell = iter->second->GetBase()->GetSpellInfo();
861
862 // Pounce Bleed shouldn't be removed by Cloak of Shadows.
863 if (spell->GetAllEffectsMechanicMask() & 1 << MECHANIC_BLEED)
864 return;
865
866 bool dmgClassNone = false;
868 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
869 {
870 if ((iter->second->GetEffectMask() & (1 << i)) &&
871 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_DAMAGE &&
872 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
873 spell->Effects[i].ApplyAuraName != SPELL_AURA_DUMMY)
874 {
875 dmgClassNone = false;
876 break;
877 }
878 dmgClassNone = true;
879 }
880
881 if ((spell->DmgClass == SPELL_DAMAGE_CLASS_MAGIC || (spell->GetDispelMask() & dispelMask) || dmgClassNone) &&
882 // ignore positive and passive auras
883 !iter->second->IsPositive() && !iter->second->GetBase()->IsPassive() &&
884 // Xinef: Ignore NPC spells having INVULNERABILITY attribute
886 {
887 m_caster->RemoveAura(iter);
888 }
889 else
890 ++iter;
891 }
892 return;
893 }
894 }
895 }
896
897 // normal case
898 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
899 if (!spellInfo)
900 {
901 LOG_DEBUG("spells.aura", "Spell::EffectTriggerSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
902 return;
903 }
904
905 SpellCastTargets targets;
907 {
908 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
909 return;
910 targets.SetUnitTarget(unitTarget);
911 }
912 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH)
913 {
914 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
915 return;
916
918 targets.SetDst(m_targets);
919
920 if (Unit* target = m_targets.GetUnitTarget())
921 targets.SetUnitTarget(target);
922 else
923 targets.SetUnitTarget(m_caster);
924 }
925
926 CustomSpellValues values;
927 // set basepoints for trigger with value effect
929 {
930 // maybe need to set value only when basepoints == 0?
934 }
935
936 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
937 if (m_caster->GetTypeId() == TYPEID_PLAYER && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
938 {
939 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
940 }
941
942 // original caster guid only for GO cast
944}
@ SPELL_AURA_MOD_STALKED
Definition: SpellAuraDefines.h:131
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
Definition: SpellAuraDefines.h:86
@ SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
Definition: SharedDefines.h:920
@ SPELL_EFFECT_TRIGGER_SPELL
Definition: SharedDefines.h:842
@ MECHANIC_BLEED
Definition: SharedDefines.h:1340
@ DISPEL_ALL
Definition: SharedDefines.h:1379

References CustomSpellValues::AddSpellMod(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, DISPEL_ALL, SpellInfo::DmgClass, EFFECT_0, effectHandleMode, SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), SpellInfo::GetCategory(), SpellInfo::GetDispelMask(), SpellInfo::GetExplicitTargetMask(), Object::GetTypeId(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, LOG_DEBUG, m_caster, m_originalCasterGUID, m_spellInfo, m_targets, MAX_SPELL_EFFECTS, MECHANIC_BLEED, SpellInfo::NeedsToBeTriggeredByCaster(), Unit::RemoveAura(), Unit::RemoveAurasByType(), Unit::RemoveMovementImpairingAuras(), Player::RemoveSpellCooldown(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), SPELL_ATTR0_NO_IMMUNITIES, SPELL_AURA_DUMMY, SPELL_AURA_MOD_STALKED, SPELL_AURA_MOD_STUN, SPELL_AURA_PERIODIC_DAMAGE, SPELL_AURA_PERIODIC_TRIGGER_SPELL, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_TRIGGER_SPELL, SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE, SPELLFAMILY_GENERIC, SpellInfo::SpellFamilyName, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, SpellInfo::StackAmount, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_UNIT_MASK, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_NO_PERIODIC_RESET, TYPEID_PLAYER, and unitTarget.

◆ EffectUnlearnSpecialization()

void Spell::EffectUnlearnSpecialization ( SpellEffIndex  effIndex)
1319{
1321 return;
1322
1323 if (!unitTarget)
1324 return;
1325
1326 Player* player = unitTarget->ToPlayer();
1327 if (!player)
1328 {
1329 return;
1330 }
1331
1332 uint32 spellToUnlearn = m_spellInfo->Effects[effIndex].TriggerSpell;
1333
1334 player->removeSpell(spellToUnlearn, SPEC_MASK_ALL, false);
1335 LOG_DEBUG("spells.aura", "Spell: Player {} has unlearned spell {} from Npc: {}",
1336 player->GetGUID().ToString(), spellToUnlearn, m_caster->GetGUID().ToString());
1337}
#define SPEC_MASK_ALL
Definition: Player.h:177
void removeSpell(uint32 spellId, uint8 removeSpecMask, bool onlyTemporary)
Definition: Player.cpp:3311

References effectHandleMode, SpellInfo::Effects, Object::GetGUID(), LOG_DEBUG, m_caster, m_spellInfo, Player::removeSpell(), SPEC_MASK_ALL, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectUntrainTalents()

void Spell::EffectUntrainTalents ( SpellEffIndex  effIndex)
2724{
2726 return;
2727
2729 return;
2730
2731 if (ObjectGuid guid = m_caster->GetGUID()) // the trainer is the caster
2733}
void SendTalentWipeConfirm(ObjectGuid guid)
Definition: Player.cpp:8834

References effectHandleMode, Object::GetGUID(), Object::GetTypeId(), m_caster, Player::SendTalentWipeConfirm(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

◆ EffectUnused()

void Spell::EffectUnused ( SpellEffIndex  effIndex)
248{
249 // NOT USED BY ANY SPELL OR USELESS OR IMPLEMENTED IN DIFFERENT WAY IN TRINITY
250}

◆ EffectWeaponDmg()

void Spell::EffectWeaponDmg ( SpellEffIndex  effIndex)
3296{
3298 return;
3299
3300 if (!unitTarget || !unitTarget->IsAlive())
3301 return;
3302
3303 // multiple weapon dmg effect workaround
3304 // execute only the last weapon damage
3305 // and handle all effects at once
3306 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
3307 {
3308 switch (m_spellInfo->Effects[j].Effect)
3309 {
3314 return; // we must calculate only at last weapon effect
3315 break;
3316 }
3317 }
3318
3319 // some spell specific modifiers
3320 float totalDamagePercentMod = 100.0f; // applied to final bonus+weapon damage
3321 int32 spell_bonus = 0; // bonus specific for spell
3322 bool normalized = false;
3323
3325 {
3327 {
3328 switch (m_spellInfo->Id)
3329 {
3330 // Trial of the Champion, Black Knight, Obliterate
3331 case 67725:
3332 case 67883:
3333 {
3334 AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), 1) * 30.0f);
3335 break;
3336 }
3337 }
3338 break;
3339 }
3341 {
3342 // Devastate (player ones)
3343 if (m_spellInfo->SpellFamilyFlags[1] & 0x40)
3344 {
3345 m_caster->CastSpell(unitTarget, 58567, true);
3346
3347 if (Aura* aur = unitTarget->GetAura(58567))
3348 {
3349 // 58388 - Glyph of Devastate dummy aura.
3350 if (m_caster->HasAura(58388))
3351 aur->ModStackAmount(1);
3352
3353 spell_bonus += (aur->GetStackAmount() - 1) * CalculateSpellDamage(2, unitTarget);
3354 }
3355 }
3356 break;
3357 }
3358 case SPELLFAMILY_ROGUE:
3359 {
3360 // Fan of Knives, Hemorrhage, Ghostly Strike
3361 if ((m_spellInfo->SpellFamilyFlags[1] & 0x40000)
3362 || (m_spellInfo->SpellFamilyFlags[0] & 0x6000000))
3363 {
3364 // Hemorrhage
3365 if (m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
3366 {
3368 }
3369 // 50% more damage with daggers
3371 if (Item* item = m_caster->ToPlayer()->GetWeaponForAttack(m_attackType, true))
3372 if (item->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER)
3373 AddPct(totalDamagePercentMod, 50.0f);
3374 }
3375 // Mutilate (for each hand)
3376 else if (m_spellInfo->SpellFamilyFlags[1] & 0x6)
3377 {
3378 bool found = false;
3379 // fast check
3381 found = true;
3382 // full aura scan
3383 else
3384 {
3386 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
3387 {
3388 if (itr->second->GetBase()->GetSpellInfo()->Dispel == DISPEL_POISON)
3389 {
3390 found = true;
3391 break;
3392 }
3393 }
3394 }
3395
3396 if (found)
3397 AddPct(totalDamagePercentMod, 20.0f); // 120% if poisoned
3398 }
3399 break;
3400 }
3402 {
3403 switch (m_spellInfo->Id)
3404 {
3405 case 20467: // Seal of Command Unleashed
3406 spell_bonus += int32(0.08f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
3408 break;
3409 case 42463: // Seals of the Pure for Seal of Vengeance/Corruption
3410 case 53739:
3412 AddPct(totalDamagePercentMod, sealsOfPure->GetAmount());
3413 break;
3414 case 53385: // Divine Storm deals normalized damage
3415 normalized = true;
3416 break;
3417 default:
3418 break;
3419 }
3420 break;
3421 }
3422 case SPELLFAMILY_SHAMAN:
3423 {
3424 // Skyshatter Harness item set bonus
3425 // Stormstrike
3426 if (AuraEffect* aurEff = m_caster->IsScriptOverriden(m_spellInfo, 5634))
3427 m_caster->CastSpell(m_caster, 38430, true, nullptr, aurEff);
3428 // Lava lash damage increased by Flametongue weapon
3430 AddPct(totalDamagePercentMod, 25.0f);
3431 break;
3432 }
3433 case SPELLFAMILY_DRUID:
3434 {
3435 // Mangle (Cat): CP
3436 if (m_spellInfo->SpellFamilyFlags[1] & 0x400)
3437 {
3439 }
3440 // Shred, Maul - Rend and Tear
3442 {
3443 if (AuraEffect const* rendAndTear = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 0))
3444 AddPct(totalDamagePercentMod, rendAndTear->GetAmount());
3445 }
3446 break;
3447 }
3448 case SPELLFAMILY_HUNTER:
3449 {
3450 // Kill Shot
3451 if( m_spellInfo->SpellFamilyFlags[1] & 0x800000 )
3452 {
3453 spell_bonus += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.4f);
3454 }
3455 break;
3456 }
3458 {
3459 // Plague Strike
3460 if (m_spellInfo->SpellFamilyFlags[0] & 0x1)
3461 {
3462 // Glyph of Plague Strike
3463 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(58657, EFFECT_0))
3464 AddPct(totalDamagePercentMod, aurEff->GetAmount());
3465 break;
3466 }
3467 // Blood Strike
3468 if (m_spellInfo->SpellFamilyFlags[0] & 0x400000)
3469 {
3470 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3471 //Death Knight T8 Melee 4P Bonus
3472 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736) )
3473 AddPct(disease_amt, aurEff->GetAmount());
3474
3475 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f);
3476
3477 // Glyph of Blood Strike
3478 if (m_caster->GetAuraEffect(59332, EFFECT_0))
3480 AddPct(totalDamagePercentMod, 20.0f);
3481 break;
3482 }
3483 // Death Strike
3484 if (m_spellInfo->SpellFamilyFlags[0] & 0x10)
3485 {
3486 // Glyph of Death Strike
3487 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(59336, EFFECT_0))
3488 if (uint32 runic = std::min<uint32>(m_caster->GetPower(POWER_RUNIC_POWER), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()))
3489 AddPct(totalDamagePercentMod, runic);
3490 break;
3491 }
3492 // Obliterate (12.5% more damage per disease)
3493 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000)
3494 {
3495 bool consumeDiseases = true;
3496 // Annihilation
3498 // Do not consume diseases if roll sucesses
3499 if (roll_chance_i(aurEff->GetAmount()))
3500 consumeDiseases = false;
3501
3502 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3503 //Death Knight T8 Melee 4P Bonus
3504 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736) )
3505 AddPct(disease_amt, aurEff->GetAmount());
3506
3507 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), consumeDiseases) / 2.0f);
3508 break;
3509 }
3510 // Blood-Caked Strike - Blood-Caked Blade
3511 if (m_spellInfo->SpellIconID == 1736)
3512 {
3513 int32 weaponDamage = m_caster->CalculateDamage(m_attackType, false, true);
3514 ApplyPct(weaponDamage, std::min(uint32(3), unitTarget->GetDiseasesByCaster(m_caster->GetGUID())) * 12.5f);
3515 spell_bonus = weaponDamage;
3516 break;
3517 }
3518 // Heart Strike
3519 if (m_spellInfo->SpellFamilyFlags[0] & 0x1000000)
3520 {
3521 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3522 //Death Knight T8 Melee 4P Bonus
3523 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736) )
3524 AddPct(disease_amt, aurEff->GetAmount());
3525
3526 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()));
3527 break;
3528 }
3529 // Rune Strike
3530 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000000)
3531 {
3532 spell_bonus += int32(0.15f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
3533 }
3534
3535 break;
3536 }
3537 }
3538
3539 float weaponDamagePercentMod = 100.0f;
3540 int32 fixed_bonus = 0;
3541
3542 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3543 {
3544 switch (m_spellInfo->Effects[j].Effect)
3545 {
3548 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3549 break;
3551 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3552 normalized = true;
3553 break;
3555 ApplyPct(weaponDamagePercentMod, CalculateSpellDamage(j, unitTarget));
3556 break;
3557 default:
3558 break; // not weapon damage effect, just skip
3559 }
3560 }
3561
3562 // apply to non-weapon bonus weapon total pct effect, weapon total flat effect included in weapon damage
3563 if (fixed_bonus || spell_bonus)
3564 {
3565 UnitMods unitMod;
3566 switch (m_attackType)
3567 {
3568 default:
3569 case BASE_ATTACK:
3570 unitMod = UNIT_MOD_DAMAGE_MAINHAND;
3571 break;
3572 case OFF_ATTACK:
3573 unitMod = UNIT_MOD_DAMAGE_OFFHAND;
3574 break;
3575 case RANGED_ATTACK:
3576 unitMod = UNIT_MOD_DAMAGE_RANGED;
3577 break;
3578 }
3579
3581 {
3582 float weapon_total_pct = m_caster->GetModifierValue(unitMod, TOTAL_PCT);
3583 fixed_bonus = int32(fixed_bonus * weapon_total_pct);
3584 spell_bonus = int32(spell_bonus * weapon_total_pct);
3585 }
3586 }
3587
3588 int32 weaponDamage = 0;
3589 // Dancing Rune Weapon
3590 if (m_caster->GetEntry() == 27893)
3591 {
3592 if (Unit* owner = m_caster->GetOwner())
3593 weaponDamage = owner->CalculateDamage(m_attackType, normalized, true);
3594 }
3595 else if (m_spellInfo->Id == 5019) // Wands
3596 {
3597 weaponDamage = m_caster->CalculateDamage(m_attackType, true, false);
3598 }
3599 else
3600 {
3601 weaponDamage = m_caster->CalculateDamage(m_attackType, normalized, true);
3602 }
3603
3604 // Sequence is important
3605 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3606 {
3607 // We assume that a spell have at most one fixed_bonus
3608 // and at most one weaponDamagePercentMod
3609 switch (m_spellInfo->Effects[j].Effect)
3610 {
3614 weaponDamage += fixed_bonus;
3615 break;
3617 ApplyPct(weaponDamage, weaponDamagePercentMod);
3618 default:
3619 break; // not weapon damage effect, just skip
3620 }
3621 }
3622
3623 weaponDamage += spell_bonus;
3624 ApplyPct(weaponDamage, totalDamagePercentMod);
3625
3626 // prevent negative damage
3627 uint32 eff_damage(std::max(weaponDamage, 0));
3628
3629 // Add melee damage bonuses (also check for negative)
3632
3633 // Meteor like spells (divided damage to targets)
3635 {
3636 uint32 count = 0;
3637 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3638 if (ihit->effectMask & (1 << effIndex))
3639 ++count;
3640
3641 eff_damage /= count; // divide to all targets
3642 }
3643
3644 m_damage += eff_damage;
3645}
@ ITEM_SUBCLASS_WEAPON_DAGGER
Definition: ItemTemplate.h:367
UnitMods
Definition: Unit.h:142
@ UNIT_MOD_DAMAGE_OFFHAND
Definition: Unit.h:166
@ UNIT_MOD_DAMAGE_RANGED
Definition: Unit.h:167
@ UNIT_MOD_DAMAGE_MAINHAND
Definition: Unit.h:165
@ TOTAL_PCT
Definition: Unit.h:129
@ SPELL_AURA_ADD_PCT_MODIFIER
Definition: SpellAuraDefines.h:171
@ POWER_RUNIC_POWER
Definition: SharedDefines.h:275
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
Definition: SharedDefines.h:899
@ SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
Definition: SharedDefines.h:809
@ AURA_STATE_DEADLY_POISON
Definition: SharedDefines.h:1308
@ AURA_STATE_BLEEDING
Definition: SharedDefines.h:1310
@ DISPEL_POISON
Definition: SharedDefines.h:1376
uint32 MeleeDamageBonusTaken(Unit *attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition: Unit.cpp:13198
uint32 GetDiseasesByCaster(ObjectGuid casterGUID, uint8 mode=0)
Definition: Unit.cpp:5766
AuraEffect * GetAuraEffectDummy(uint32 spellid) const
Definition: Unit.cpp:5495
float GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const
Definition: Unit.cpp:15202
uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, uint8 itemDamagesMask=0)
Definition: Unit.cpp:2948
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask)
Definition: Unit.cpp:11859
uint32 MeleeDamageBonusDone(Unit *pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition: Unit.cpp:12996

References AddComboPointGain(), AddPct(), ApplyPct(), AURA_STATE_BLEEDING, AURA_STATE_DEADLY_POISON, BASE_ATTACK, Unit::CalculateDamage(), CalculateSpellDamage(), Unit::CastSpell(), DISPEL_POISON, EFFECT_0, EFFECT_1, EFFECT_2, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetAura(), Unit::GetAuraEffect(), Unit::GetAuraEffectDummy(), Unit::GetDiseasesByCaster(), Unit::GetDummyAuraEffect(), Object::GetEntry(), Object::GetGUID(), Unit::GetModifierValue(), Unit::GetOwner(), Unit::GetPower(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), Object::GetTypeId(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), Unit::HasAuraType(), SpellInfo::Id, Unit::IsAlive(), Unit::IsScriptOverriden(), ITEM_SUBCLASS_WEAPON_DAGGER, m_attackType, m_caster, m_damage, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::MeleeDamageBonusDone(), Unit::MeleeDamageBonusTaken(), OFF_ATTACK, POWER_RUNIC_POWER, RANGED_ATTACK, roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_ADD_PCT_MODIFIER, SPELL_AURA_DUMMY, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, Unit::SpellBaseDamageBonusDone(), SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_DRUID, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, Object::ToPlayer(), TOTAL_PCT, TYPEID_PLAYER, UNIT_MOD_DAMAGE_MAINHAND, UNIT_MOD_DAMAGE_OFFHAND, UNIT_MOD_DAMAGE_RANGED, and unitTarget.

◆ ExecuteLogEffectCreateItem()

void Spell::ExecuteLogEffectCreateItem ( uint8  effIndex,
uint32  entry 
)
5131{
5132 InitEffectExecuteData(effIndex);
5133 *m_effectExecuteData[effIndex] << uint32(entry);
5134}
void InitEffectExecuteData(uint8 effIndex)
Definition: Spell.cpp:8459

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectCreateItem().

◆ ExecuteLogEffectDestroyItem()

void Spell::ExecuteLogEffectDestroyItem ( uint8  effIndex,
uint32  entry 
)
5137{
5138 InitEffectExecuteData(effIndex);
5139 *m_effectExecuteData[effIndex] << uint32(entry);
5140}

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectFeedPet().

◆ ExecuteLogEffectDurabilityDamage()

void Spell::ExecuteLogEffectDurabilityDamage ( uint8  effIndex,
Unit victim,
int32  itemId,
int32  slot 
)
5117{
5118 InitEffectExecuteData(effIndex);
5119 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5120 *m_effectExecuteData[effIndex] << int32(itemId);
5121 *m_effectExecuteData[effIndex] << int32(slot);
5122}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectDurabilityDamage().

◆ ExecuteLogEffectExtraAttacks()

void Spell::ExecuteLogEffectExtraAttacks ( uint8  effIndex,
Unit victim,
uint32  attCount 
)
5103{
5104 InitEffectExecuteData(effIndex);
5105 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5106 *m_effectExecuteData[effIndex] << uint32(attCount);
5107}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectAddExtraAttacks().

◆ ExecuteLogEffectInterruptCast()

void Spell::ExecuteLogEffectInterruptCast ( uint8  effIndex,
Unit victim,
uint32  spellId 
)
5110{
5111 InitEffectExecuteData(effIndex);
5112 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5113 *m_effectExecuteData[effIndex] << uint32(spellId);
5114}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectInterruptCast().

◆ ExecuteLogEffectOpenLock()

void Spell::ExecuteLogEffectOpenLock ( uint8  effIndex,
Object obj 
)
5125{
5126 InitEffectExecuteData(effIndex);
5127 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5128}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectOpenLock().

◆ ExecuteLogEffectResurrect()

void Spell::ExecuteLogEffectResurrect ( uint8  effIndex,
Unit target 
)
5155{
5156 InitEffectExecuteData(effIndex);
5157 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5158}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ ExecuteLogEffectSummonObject()

◆ ExecuteLogEffectTakeTargetPower()

void Spell::ExecuteLogEffectTakeTargetPower ( uint8  effIndex,
Unit target,
uint32  PowerType,
uint32  powerTaken,
float  gainMultiplier 
)
5094{
5095 InitEffectExecuteData(effIndex);
5096 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5097 *m_effectExecuteData[effIndex] << uint32(powerTaken);
5098 *m_effectExecuteData[effIndex] << uint32(PowerType);
5099 *m_effectExecuteData[effIndex] << float(gainMultiplier);
5100}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectPowerBurn(), EffectPowerDrain(), and spell_mage_burnout_trigger::HandleDummy().

◆ ExecuteLogEffectUnsummonObject()

void Spell::ExecuteLogEffectUnsummonObject ( uint8  effIndex,
WorldObject obj 
)
5149{
5150 InitEffectExecuteData(effIndex);
5151 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5152}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectDismissPet().

◆ finish()

void Spell::finish ( bool  ok = true)
4474{
4475 if (!m_caster)
4476 return;
4477
4479 return;
4481
4482 if (m_spellInfo->IsChanneled())
4484
4487
4488 // Unsummon summon as possessed creatures on spell cancel
4490 {
4491 if (Unit* charm = m_caster->GetCharm())
4492 if (charm->GetTypeId() == TYPEID_UNIT
4493 && charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET)
4494 && charm->GetUInt32Value(UNIT_CREATED_BY_SPELL) == m_spellInfo->Id)
4495 ((Puppet*)charm)->UnSummon();
4496 }
4497
4498 if (Creature* creatureCaster = m_caster->ToCreature())
4499 creatureCaster->ReleaseFocus(this);
4500
4501 if (!ok)
4502 {
4504 {
4505 // Xinef: Restore spell mods in case of fail cast
4507
4508 // Xinef: Reset cooldown event in case of fail cast
4511 }
4512 return;
4513 }
4514
4515 // pussywizard:
4518
4520 {
4521 // Unsummon statue
4523 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
4524 if (spellInfo && spellInfo->SpellIconID == 2056)
4525 {
4526 LOG_DEBUG("spells.aura", "Statue {} is unsummoned in spell {} finish", m_caster->GetGUID().ToString(), m_spellInfo->Id);
4527 m_caster->setDeathState(DeathState::JustDied);
4528 return;
4529 }
4530 }
4531
4532 // potions disabled by client, send event "not in combat" if need
4535
4536 // Take mods after trigger spell (needed for 14177 to affect 48664)
4537 // mods are taken only on succesfull cast and independantly from targets of the spell
4538 if (Player* player = m_caster->GetSpellModOwner())
4539 player->RemoveSpellMods(this);
4540
4541 // xinef: clear reactive auras states after spell cast
4544
4545 // Stop Attack for some spells
4548}
@ UNIT_MASK_PUPPET
Definition: UnitDefines.h:141
@ ENCOUNTER_CREDIT_CAST_SPELL
Definition: Map.h:309
@ SPELL_ATTR0_CU_ENCOUNTER_REWARD
Definition: SpellInfo.h:207
@ AURA_STATE_DEFENSE
Definition: SharedDefines.h:1292
@ AURA_STATE_HUNTER_PARRY
Definition: SharedDefines.h:1298
Definition: TemporarySummon.h:114
void UpdatePotionCooldown(Spell *spell=nullptr)
Definition: PlayerUpdates.cpp:1497
virtual void setDeathState(DeathState s, bool despawn=false)
Definition: Unit.cpp:14466
void UpdateInterruptMask()
Definition: Unit.cpp:741
void ModifyAuraState(AuraStateType flag, bool apply)
Definition: Unit.cpp:10424
void UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit *source)
Definition: Map.cpp:3471

References Unit::AttackStop(), AURA_STATE_DEFENSE, AURA_STATE_HUNTER_PARRY, SpellInfo::CasterAuraState, Unit::ClearUnitState(), ENCOUNTER_CREDIT_CAST_SPELL, WorldObject::FindMap(), Unit::GetCharm(), Object::GetGUID(), Unit::GetSpellModOwner(), Object::GetTypeId(), Object::GetUInt32Value(), SpellInfo::HasAttribute(), Unit::HasUnitState(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsCooldownStartedOnEvent(), Unit::IsNonMeleeSpellCast(), Unit::IsSummon(), LOG_DEBUG, m_caster, m_spellInfo, m_spellState, m_triggeredByAuraSpell, Unit::ModifyAuraState(), Player::RestoreSpellMods(), Player::SendCooldownEvent(), Unit::setDeathState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_ENCOUNTER_REWARD, SPELL_STATE_FINISHED, SpellInfo::SpellIconID, sSpellMgr, Object::ToCreature(), Object::ToPlayer(), ObjectGuid::ToString(), TYPEID_PLAYER, TYPEID_UNIT, UNIT_CREATED_BY_SPELL, UNIT_MASK_PUPPET, UNIT_STATE_CASTING, Map::UpdateEncounterState(), Unit::UpdateInterruptMask(), and Player::UpdatePotionCooldown().

Referenced by _cast(), Unit::AttackerStateUpdate(), cancel(), EffectInstaKill(), EffectTameCreature(), EffectTriggerRitualOfSummoning(), SpellScript::FinishCast(), Unit::FinishSpell(), handle_delayed(), handle_immediate(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and update().

◆ FinishTargetProcessing()

void Spell::FinishTargetProcessing ( )
protected
8455{
8457}
void SendLogExecute()
Definition: Spell.cpp:5059

References SendLogExecute().

Referenced by handle_delayed(), handle_immediate(), and HandleLaunchPhase().

◆ GetCaster()

Unit * Spell::GetCaster ( ) const
inline

◆ GetCastTime()

int32 Spell::GetCastTime ( ) const
inline
547{ return m_casttime; }

References m_casttime.

Referenced by Unit::InterruptSpell(), and Unit::SetCurrentCastedSpell().

◆ GetCurrentContainer()

CurrentSpellTypes Spell::GetCurrentContainer ( ) const

◆ GetDebugInfo()

std::string Spell::GetDebugInfo ( ) const
protected
8918{
8919 std::stringstream sstr;
8920 sstr << std::boolalpha
8921 << "Id: " << GetSpellInfo()->Id << " OriginalCaster: " << m_originalCasterGUID.ToString()
8922 << " State: " << getState();
8923 return sstr.str();
8924}

References GetSpellInfo(), getState(), SpellInfo::Id, m_originalCasterGUID, and ObjectGuid::ToString().

◆ GetDelayMoment()

uint64 Spell::GetDelayMoment ( ) const
inline

◆ GetDelayStart()

uint64 Spell::GetDelayStart ( ) const
inline
562{ return m_delayStart; }

References m_delayStart.

Referenced by SpellEvent::Execute(), and RecalculateDelayMomentForDst().

◆ GetDelayTrajectory()

uint64 Spell::GetDelayTrajectory ( ) const
inline
565{ return m_delayTrajectory; }

References m_delayTrajectory.

◆ GetOriginalCaster()

Unit * Spell::GetOriginalCaster ( ) const
inline

◆ GetPowerCost()

int32 Spell::GetPowerCost ( ) const
inline
576{ return m_powerCost; }

References m_powerCost.

Referenced by Unit::HandleDummyAuraProc().

◆ GetSearcherTypeMask()

uint32 Spell::GetSearcherTypeMask ( SpellTargetObjectTypes  objType,
ConditionList condList 
)
2110{
2111 // this function selects which containers need to be searched for spell target
2113
2114 // filter searchers based on searched object type
2115 switch (objType)
2116 {
2123 break;
2127 break;
2128 default:
2129 break;
2130 }
2132 retMask &= ~GRID_MAP_TYPE_MASK_CORPSE;
2136 retMask &= GRID_MAP_TYPE_MASK_PLAYER;
2137
2138 if (condList)
2139 retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
2140 return retMask;
2141}
@ GRID_MAP_TYPE_MASK_PLAYER
Definition: GridDefines.h:73
@ GRID_MAP_TYPE_MASK_CREATURE
Definition: GridDefines.h:70
@ GRID_MAP_TYPE_MASK_ALL
Definition: GridDefines.h:74
@ GRID_MAP_TYPE_MASK_GAMEOBJECT
Definition: GridDefines.h:72
@ GRID_MAP_TYPE_MASK_CORPSE
Definition: GridDefines.h:69
@ TARGET_OBJECT_TYPE_CORPSE
Definition: SpellInfo.h:106
@ TARGET_OBJECT_TYPE_GOBJ
Definition: SpellInfo.h:103
@ TARGET_OBJECT_TYPE_CORPSE_ALLY
Definition: SpellInfo.h:109
@ TARGET_OBJECT_TYPE_CORPSE_ENEMY
Definition: SpellInfo.h:108
@ TARGET_OBJECT_TYPE_GOBJ_ITEM
Definition: SpellInfo.h:104
@ SPELL_ATTR2_ALLOW_DEAD_TARGET
Definition: SharedDefines.h:456
@ SPELL_ATTR3_ONLY_ON_GHOSTS
Definition: SharedDefines.h:505
@ SPELL_ATTR3_ONLY_ON_PLAYER
Definition: SharedDefines.h:501

References GRID_MAP_TYPE_MASK_ALL, GRID_MAP_TYPE_MASK_CORPSE, GRID_MAP_TYPE_MASK_CREATURE, GRID_MAP_TYPE_MASK_GAMEOBJECT, GRID_MAP_TYPE_MASK_PLAYER, SpellInfo::HasAttribute(), m_spellInfo, sConditionMgr, SPELL_ATTR2_ALLOW_DEAD_TARGET, SPELL_ATTR3_ONLY_ON_GHOSTS, SPELL_ATTR3_ONLY_ON_PLAYER, TARGET_OBJECT_TYPE_CORPSE, TARGET_OBJECT_TYPE_CORPSE_ALLY, TARGET_OBJECT_TYPE_CORPSE_ENEMY, TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_GOBJ_ITEM, TARGET_OBJECT_TYPE_UNIT, and TARGET_OBJECT_TYPE_UNIT_AND_DEST.

Referenced by SearchAreaTargets(), SearchNearbyTarget(), and SelectImplicitConeTargets().

◆ GetSpellInfo()

◆ GetSpellSchoolMask()

SpellSchoolMask Spell::GetSpellSchoolMask ( ) const
inline

◆ GetSpellValue()

SpellValue const * Spell::GetSpellValue ( )
inline
583{ return m_spellValue; }

References m_spellValue.

Referenced by DoAllEffectOnTarget().

◆ getState()

◆ GetTriggeredByAuraTickNumber()

uint32 Spell::GetTriggeredByAuraTickNumber ( ) const
inline

◆ GetTriggeredCastFlags()

TriggerCastFlags Spell::GetTriggeredCastFlags ( ) const
inline
591{ return _triggeredCastFlags; }

References _triggeredCastFlags.

◆ GetUniqueTargetInfo()

◆ handle_delayed()

uint64 Spell::handle_delayed ( uint64  t_offset)
4167{
4168 if (!UpdatePointers())
4169 {
4170 // finish the spell if UpdatePointers() returned false, something wrong happened there
4171 finish(false);
4172 return 0;
4173 }
4174
4175 Player* modOwner = m_caster->GetSpellModOwner();
4176 if (modOwner)
4177 modOwner->SetSpellModTakingSpell(this, true);
4178
4179 uint64 next_time = m_delayTrajectory;
4180
4182
4183 if (!m_immediateHandled && m_delayTrajectory <= t_offset)
4184 {
4186 m_immediateHandled = true;
4188 next_time = 0;
4189 }
4190
4191 bool single_missile = (m_targets.HasDst());
4192
4193 // now recheck units targeting correctness (need before any effects apply to prevent adding immunity at first effect not allow apply second spell effect and similar cases)
4194 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4195 {
4196 if (ihit->processed == false)
4197 {
4198 if (single_missile || ihit->timeDelay <= t_offset)
4199 {
4200 ihit->timeDelay = t_offset;
4201 DoAllEffectOnTarget(&(*ihit));
4202 }
4203 else if (next_time == 0 || ihit->timeDelay < next_time)
4204 next_time = ihit->timeDelay;
4205 }
4206 }
4207
4208 // now recheck gameobject targeting correctness
4209 for (std::list<GOTargetInfo>::iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
4210 {
4211 if (ighit->processed == false)
4212 {
4213 if (single_missile || ighit->timeDelay <= t_offset)
4214 DoAllEffectOnTarget(&(*ighit));
4215 else if (next_time == 0 || ighit->timeDelay < next_time)
4216 next_time = ighit->timeDelay;
4217 }
4218 }
4219
4221
4222 if (modOwner)
4223 modOwner->SetSpellModTakingSpell(this, false);
4224
4225 // All targets passed - need finish phase
4226 if (next_time == 0)
4227 {
4228 // spell is finished, perform some last features of the spell here
4230
4231 finish(true); // successfully finish spell cast
4232
4233 // return zero, spell is finished now
4234 return 0;
4235 }
4236 else
4237 {
4238 // spell is unfinished, return next execution time
4239 return next_time;
4240 }
4241}
void _handle_finish_phase()
Definition: Spell.cpp:4271
void PrepareTargetProcessing()
Definition: Spell.cpp:8449
void _handle_immediate_phase()
Definition: Spell.cpp:4243
void FinishTargetProcessing()
Definition: Spell.cpp:8454

References _handle_finish_phase(), _handle_immediate_phase(), DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), Unit::GetSpellModOwner(), SpellCastTargets::HasDst(), m_caster, m_delayTrajectory, m_immediateHandled, m_targets, m_UniqueGOTargetInfo, m_UniqueTargetInfo, PrepareTargetProcessing(), Player::SetSpellModTakingSpell(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ handle_immediate()

void Spell::handle_immediate ( )
4107{
4108 // start channeling if applicable
4109 if (m_spellInfo->IsChanneled())
4110 {
4111 int32 duration = m_spellInfo->GetDuration();
4113 duration = -1;
4114
4115 if (duration > 0)
4116 {
4117 // First mod_duration then haste - see Missile Barrage
4118 // Apply duration mod
4119 if (Player* modOwner = m_caster->GetSpellModOwner())
4120 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
4121
4122 // Apply haste mods
4124 duration = int32(duration * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
4125
4128 m_channeledDuration = duration;
4129 SendChannelStart(duration);
4130 }
4131 else if (duration == -1)
4132 {
4135 SendChannelStart(duration);
4136 }
4137 }
4138
4140
4141 // process immediate effects (items, ground, etc.) also initialize some variables
4143
4144 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4145 DoAllEffectOnTarget(&(*ihit));
4146
4147 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
4148 DoAllEffectOnTarget(&(*ihit));
4149
4151
4152 // spell is finished, perform some last features of the spell here
4154
4155 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4156 TakeCastItem();
4157
4158 // handle ammo consumption for Hunter's volley spell
4160 TakeAmmo();
4161
4163 finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
4164}
void AddInterruptMask(uint32 mask)
Definition: Unit.h:1505
void SendChannelStart(uint32 duration)
Definition: Spell.cpp:5192
void TakeAmmo()
Definition: Spell.cpp:5365

References _handle_finish_phase(), _handle_immediate_phase(), Unit::AddInterruptMask(), SpellInfo::ChannelInterruptFlags, DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), SpellInfo::GetDuration(), Object::GetFloatValue(), Unit::GetSpellModOwner(), SpellInfo::HasAttribute(), Unit::HasAuraTypeWithAffectMask(), HasTriggeredCastFlag(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsRangedWeaponSpell(), m_caster, m_channeledDuration, m_spellInfo, m_spellState, m_UniqueGOTargetInfo, m_UniqueTargetInfo, PrepareTargetProcessing(), SendChannelStart(), SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_PERIODIC_HASTE, SPELL_STATE_CASTING, SPELLMOD_DURATION, TakeAmmo(), TakeCastItem(), TRIGGERED_IGNORE_EFFECTS, and UNIT_MOD_CAST_SPEED.

Referenced by _cast().

◆ HandleEffects()

void Spell::HandleEffects ( Unit pUnitTarget,
Item pItemTarget,
GameObject pGOTarget,
uint32  i,
SpellEffectHandleMode  mode 
)
5614{
5616 return;
5617
5618 effectHandleMode = mode;
5619 unitTarget = pUnitTarget;
5620 itemTarget = pItemTarget;
5621 gameObjTarget = pGOTarget;
5623
5624 uint8 eff = m_spellInfo->Effects[i].Effect;
5625
5626 LOG_DEBUG("spells.aura", "Spell: {} Effect : {}", m_spellInfo->Id, eff);
5627
5628 // we do not need DamageMultiplier here.
5629 damage = CalculateSpellDamage(i, nullptr);
5630
5631 bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
5632
5633 if (!preventDefault && eff < TOTAL_SPELL_EFFECTS)
5634 {
5635 (this->*SpellEffects[eff])((SpellEffIndex)i);
5636 }
5637}
SpellEffIndex
Definition: SharedDefines.h:30
SpellEffects
Definition: SharedDefines.h:778
@ TOTAL_SPELL_EFFECTS
Definition: SharedDefines.h:943
WorldLocation _position
Definition: Spell.h:103
bool CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode)
Definition: Spell.cpp:8568

References SpellDestination::_position, CalculateSpellDamage(), CallScriptEffectHandlers(), damage, destTarget, effectHandleMode, SpellInfo::Effects, gameObjTarget, HasTriggeredCastFlag(), SpellInfo::Id, itemTarget, LOG_DEBUG, m_destTargets, m_spellInfo, TOTAL_SPELL_EFFECTS, TRIGGERED_IGNORE_EFFECTS, and unitTarget.

Referenced by _handle_immediate_phase(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), and HandleLaunchPhase().

◆ HandleLaunchPhase()

void Spell::HandleLaunchPhase ( )
protected
8218{
8219 // handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode
8220 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8221 {
8222 // don't do anything for empty effect
8223 if (!m_spellInfo->Effects[i].IsEffect())
8224 continue;
8225
8226 HandleEffects(nullptr, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH);
8227 }
8228
8229 float multiplier[MAX_SPELL_EFFECTS];
8230 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8231 if (m_applyMultiplierMask & (1 << i))
8232 multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this);
8233
8236 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
8237 {
8238 if ((*j)->IsAffectedOnSpell(m_spellInfo))
8239 usesAmmo = false;
8240 }
8241
8243
8244 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
8245 {
8246 TargetInfo& target = *ihit;
8247
8248 uint32 mask = target.effectMask;
8249 if (!mask)
8250 continue;
8251
8252 // do not consume ammo anymore for Hunter's volley spell
8254 usesAmmo = false;
8255
8256 if (usesAmmo)
8257 {
8258 bool ammoTaken = false;
8259 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
8260 {
8261 if (!(mask & 1 << i))
8262 continue;
8263 switch (m_spellInfo->Effects[i].Effect)
8264 {
8270 ammoTaken = true;
8271 TakeAmmo();
8272 }
8273 if (ammoTaken)
8274 break;
8275 }
8276 }
8277
8278 DoAllEffectOnLaunchTarget(target, multiplier);
8279 }
8280
8282}
@ SPELL_AURA_ABILITY_CONSUME_NO_AMMO
Definition: SpellAuraDefines.h:337
@ SPELL_ATTR0_CU_DIRECT_DAMAGE
Definition: SpellInfo.h:184
@ SPELL_EFFECT_SCHOOL_DAMAGE
Definition: SharedDefines.h:780
void DoAllEffectOnLaunchTarget(TargetInfo &targetInfo, float *multiplier)
Definition: Spell.cpp:8284

References DoAllEffectOnLaunchTarget(), TargetInfo::effectMask, SpellInfo::Effects, FinishTargetProcessing(), Unit::GetAuraEffectsByType(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::IsTargetingArea(), IsTriggered(), m_applyMultiplierMask, m_caster, m_originalCaster, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, PrepareTargetProcessing(), SPELL_ATTR0_CU_DIRECT_DAMAGE, SPELL_AURA_ABILITY_CONSUME_NO_AMMO, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_SCHOOL_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELLFAMILY_HUNTER, SpellInfo::SpellFamilyName, and TakeAmmo().

Referenced by _cast().

◆ HandleThreatSpells()

void Spell::HandleThreatSpells ( )
5567{
5568 if (m_UniqueTargetInfo.empty())
5569 return;
5570
5572 return;
5573
5574 float threat = 0.0f;
5575 if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(m_spellInfo->Id))
5576 {
5577 if (threatEntry->apPctMod != 0.0f)
5578 threat += threatEntry->apPctMod * m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
5579
5580 threat += threatEntry->flatMod;
5581 }
5583 threat += m_spellInfo->SpellLevel;
5584
5585 // past this point only multiplicative effects occur
5586 if (threat == 0.0f)
5587 return;
5588
5589 // since 2.0.1 threat from positive effects also is distributed among all targets, so the overall caused threat is at most the defined bonus
5590 threat /= m_UniqueTargetInfo.size();
5591
5592 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5593 {
5594 float threatToAdd = threat;
5595 if (ihit->missCondition != SPELL_MISS_NONE)
5596 threatToAdd = 0.0f;
5597
5598 Unit* target = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
5599 if (!target)
5600 continue;
5601
5602 bool IsFriendly = m_caster->IsFriendlyTo(target);
5603 // positive spells distribute threat among all units that are in combat with target, like healing
5605 target->getHostileRefMgr().threatAssist(m_caster, threatToAdd, m_spellInfo);
5606 // for negative spells threat gets distributed among affected targets
5607 else if (!m_spellInfo->_IsPositiveSpell() && !IsFriendly && target->CanHaveThreatList())
5608 target->AddThreat(m_caster, threatToAdd, m_spellInfo->GetSchoolMask(), m_spellInfo);
5609 }
5610 LOG_DEBUG("spells.aura", "Spell {}, added an additional {} threat for {} {} target(s)", m_spellInfo->Id, threat, m_spellInfo->_IsPositiveSpell() ? "assisting" : "harming", uint32(m_UniqueTargetInfo.size()));
5611}
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition: SpellInfo.h:180
static bool IsFriendly(Creature *piece, Creature *target)
Definition: boss_chess_event.cpp:178
bool _IsPositiveSpell() const
Definition: SpellInfo.cpp:2839
Definition: SpellMgr.h:385

References SpellInfo::_IsPositiveSpell(), Unit::AddThreat(), BASE_ATTACK, Unit::CanHaveThreatList(), Unit::getHostileRefMgr(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, IsFriendly(), Unit::IsFriendlyTo(), LOG_DEBUG, m_caster, m_spellInfo, m_UniqueTargetInfo, SPELL_ATTR0_CU_NO_INITIAL_THREAT, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPRESS_TARGET_PROCS, SPELL_MISS_NONE, SpellInfo::SpellLevel, sSpellMgr, and HostileRefMgr::threatAssist().

Referenced by _handle_immediate_phase().

◆ HasGlobalCooldown()

bool Spell::HasGlobalCooldown ( ) const
protected

◆ HasTriggeredCastFlag()

◆ HaveTargetsForEffect()

bool Spell::HaveTargetsForEffect ( uint8  effect) const
8088{
8089 for (std::list<TargetInfo>::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
8090 if (itr->effectMask & (1 << effect))
8091 return true;
8092
8093 for (std::list<GOTargetInfo>::const_iterator itr = m_UniqueGOTargetInfo.begin(); itr != m_UniqueGOTargetInfo.end(); ++itr)
8094 if (itr->effectMask & (1 << effect))
8095 return true;
8096
8097 for (std::list<ItemTargetInfo>::const_iterator itr = m_UniqueItemInfo.begin(); itr != m_UniqueItemInfo.end(); ++itr)
8098 if (itr->effectMask & (1 << effect))
8099 return true;
8100
8101 return false;
8102}

References m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

◆ InitEffectExecuteData()

void Spell::InitEffectExecuteData ( uint8  effIndex)
protected
8460{
8461 ASSERT(effIndex < MAX_SPELL_EFFECTS);
8462 if (!m_effectExecuteData[effIndex])
8463 {
8464 m_effectExecuteData[effIndex] = new ByteBuffer(0x20);
8465 // first dword - target counter
8466 *m_effectExecuteData[effIndex] << uint32(1);
8467 }
8468 else
8469 {
8470 // increase target counter by one
8471 uint32 count = (*m_effectExecuteData[effIndex]).read<uint32>(0);
8472 (*m_effectExecuteData[effIndex]).put<uint32>(0, ++count);
8473 }
8474}

References ASSERT, m_effectExecuteData, and MAX_SPELL_EFFECTS.

Referenced by ExecuteLogEffectCreateItem(), ExecuteLogEffectDestroyItem(), ExecuteLogEffectDurabilityDamage(), ExecuteLogEffectExtraAttacks(), ExecuteLogEffectInterruptCast(), ExecuteLogEffectOpenLock(), ExecuteLogEffectResurrect(), ExecuteLogEffectSummonObject(), ExecuteLogEffectTakeTargetPower(), and ExecuteLogEffectUnsummonObject().

◆ InitExplicitTargets()

void Spell::InitExplicitTargets ( SpellCastTargets const &  targets)
714{
715 m_targets = targets;
716 // this function tries to correct spell explicit targets for spell
717 // client doesn't send explicit targets correctly sometimes - we need to fix such spells serverside
718 // this also makes sure that we correctly send explicit targets to client (removes redundant data)
719 uint32 neededTargets = m_spellInfo->GetExplicitTargetMask();
720
721 if (WorldObject* target = m_targets.GetObjectTarget())
722 {
723 // check if object target is valid with needed target flags
724 // for unit case allow corpse target mask because player with not released corpse is a unit target
725 if ((target->ToUnit() && !(neededTargets & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK)))
726 || (target->ToGameObject() && !(neededTargets & TARGET_FLAG_GAMEOBJECT_MASK))
727 || (target->ToCorpse() && !(neededTargets & TARGET_FLAG_CORPSE_MASK)))
729 }
730 else
731 {
732 // try to select correct unit target if not provided by client or by serverside cast
733 if (neededTargets & (TARGET_FLAG_UNIT_MASK))
734 {
735 Unit* unit = nullptr;
736 // try to use player selection as a target
737 if (Player* playerCaster = m_caster->ToPlayer())
738 {
739 // selection has to be found and to be valid target for the spell
740 if (Unit* selectedUnit = ObjectAccessor::GetUnit(*m_caster, playerCaster->GetTarget()))
742 unit = selectedUnit;
743 }
744 // try to use attacked unit as a target
745 else if ((m_caster->GetTypeId() == TYPEID_UNIT) && neededTargets & (TARGET_FLAG_UNIT_ENEMY | TARGET_FLAG_UNIT))
746 unit = m_caster->GetVictim();
747
748 // didn't find anything - let's use self as target
749 if (!unit && neededTargets & (TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY | TARGET_FLAG_UNIT_ALLY))
750 unit = m_caster;
751
753 }
754 }
755
756 // check if spell needs dst target
757 if (neededTargets & TARGET_FLAG_DEST_LOCATION)
758 {
759 // and target isn't set
760 if (!m_targets.HasDst())
761 {
762 // try to use unit target if provided
763 if (WorldObject* target = targets.GetObjectTarget())
764 m_targets.SetDst(*target);
765 // or use self if not available
766 else
768 }
769 }
770 else
772
773 if (neededTargets & TARGET_FLAG_SOURCE_LOCATION)
774 {
775 if (!targets.HasSrc())
777 }
778 else
780}
@ TARGET_FLAG_UNIT_RAID
Definition: SpellInfo.h:48
@ TARGET_FLAG_UNIT_ALLY
Definition: SpellInfo.h:54
@ TARGET_FLAG_SOURCE_LOCATION
Definition: SpellInfo.h:51
@ TARGET_FLAG_CORPSE_MASK
Definition: SpellInfo.h:71
@ TARGET_FLAG_UNIT_PARTY
Definition: SpellInfo.h:49
void RemoveObjectTarget()
Definition: Spell.cpp:321
void RemoveDst()
Definition: Spell.cpp:448
void RemoveSrc()
Definition: Spell.cpp:391

References SpellInfo::CheckExplicitTarget(), SpellInfo::GetExplicitTargetMask(), SpellCastTargets::GetObjectTarget(), Unit::GetTarget(), Object::GetTypeId(), ObjectAccessor::GetUnit(), Unit::GetVictim(), SpellCastTargets::HasDst(), SpellCastTargets::HasSrc(), m_caster, m_spellInfo, m_targets, SpellCastTargets::RemoveDst(), SpellCastTargets::RemoveObjectTarget(), SpellCastTargets::RemoveSrc(), SpellCastTargets::SetDst(), SpellCastTargets::SetSrc(), SpellCastTargets::SetUnitTarget(), SPELL_CAST_OK, TARGET_FLAG_CORPSE_MASK, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_SOURCE_LOCATION, TARGET_FLAG_UNIT, TARGET_FLAG_UNIT_ALLY, TARGET_FLAG_UNIT_ENEMY, TARGET_FLAG_UNIT_MASK, TARGET_FLAG_UNIT_PARTY, TARGET_FLAG_UNIT_RAID, Object::ToPlayer(), and TYPEID_UNIT.

Referenced by Player::CastItemUseSpell(), and prepare().

◆ IsAutoActionResetSpell()

bool Spell::IsAutoActionResetSpell ( ) const
Todo:
changed SPELL_INTERRUPT_FLAG_AUTOATTACK -> SPELL_INTERRUPT_FLAG_INTERRUPT to fix compile - is this check correct at all?
8062{
8065 {
8066 return false;
8067 }
8068
8070 {
8071 return false;
8072 }
8073
8074 return true;
8075}
@ SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT
Definition: SharedDefines.h:629

References SpellInfo::HasAttribute(), SpellInfo::InterruptFlags, IsTriggered(), m_casttime, m_spellInfo, SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT, and SPELL_INTERRUPT_FLAG_INTERRUPT.

Referenced by _cast().

◆ IsAutoRepeat()

bool Spell::IsAutoRepeat ( ) const
inline

◆ IsChannelActive()

bool Spell::IsChannelActive ( ) const
inline
@ UNIT_CHANNEL_SPELL
Definition: UpdateFields.h:94

References Object::GetUInt32Value(), m_caster, and UNIT_CHANNEL_SPELL.

Referenced by Creature::IsMovementPreventedByCasting().

◆ isDelayableNoMore()

bool Spell::isDelayableNoMore ( )
inlineprotected
629 {
630 if (m_delayAtDamageCount >= 2)
631 return true;
632
634 return false;
635 }

References m_delayAtDamageCount.

Referenced by Delayed(), and DelayedChannel().

◆ IsDeletable()

◆ IsIgnoringCooldowns()

bool Spell::IsIgnoringCooldowns ( ) const

◆ IsInterruptable()

bool Spell::IsInterruptable ( ) const
inline
560{ return !m_executedCurrently; }

References m_executedCurrently.

Referenced by Unit::InterruptSpell().

◆ IsNeedSendToClient()

◆ IsNextMeleeSwingSpell()

bool Spell::IsNextMeleeSwingSpell ( ) const

◆ IsTriggered()

◆ IsValidDeadOrAliveTarget()

bool Spell::IsValidDeadOrAliveTarget ( Unit const *  target) const
protected
8210{
8211 if (target->IsAlive())
8213
8215}
bool IsRequiringDeadTarget() const
Definition: SpellInfo.cpp:1221
bool IsAllowingDeadTarget() const
Definition: SpellInfo.cpp:1226

References Unit::IsAlive(), SpellInfo::IsAllowingDeadTarget(), SpellInfo::IsRequiringDeadTarget(), and m_spellInfo.

Referenced by UpdateChanneledTargetList().

◆ LoadScripts()

void Spell::LoadScripts ( )
8483{
8484 if (_scriptsLoaded)
8485 return;
8486 _scriptsLoaded = true;
8487 sScriptMgr->CreateSpellScripts(m_spellInfo->Id, m_loadedScripts);
8488 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end();)
8489 {
8490 if (!(*itr)->_Load(this))
8491 {
8492 std::list<SpellScript*>::iterator bitr = itr;
8493 ++itr;
8494 delete (*bitr);
8495 m_loadedScripts.erase(bitr);
8496 continue;
8497 }
8498 LOG_DEBUG("spells.aura", "Spell::LoadScripts: Script `{}` for spell `{}` is loaded now", (*itr)->_GetScriptName()->c_str(), m_spellInfo->Id);
8499 (*itr)->Register();
8500 ++itr;
8501 }
8502}

References _scriptsLoaded, SpellInfo::Id, LOG_DEBUG, m_loadedScripts, m_spellInfo, and sScriptMgr.

Referenced by WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), prepare(), and PetAI::UpdateAI().

◆ OnSpellLaunch()

void Spell::OnSpellLaunch ( )
8888{
8889 if (!m_caster || !m_caster->IsInWorld())
8890 return;
8891
8892 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(24390);
8893
8894 // Make sure the player is sending a valid GO target and lock ID. SPELL_EFFECT_OPEN_LOCK
8895 // can succeed with a lockId of 0
8896 if (m_spellInfo->Id == 21651)
8897 {
8898 if (GameObject* go = m_targets.GetGOTarget())
8899 {
8900 LockEntry const* lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->GetLockId());
8901 if (lockInfo && lockInfo->Index[1] == LOCKTYPE_SLOW_OPEN)
8902 {
8903 Spell* visual = new Spell(m_caster, spellInfo, TRIGGERED_NONE);
8904 visual->prepare(&m_targets);
8905 }
8906 }
8907 }
8908}
@ TRIGGERED_NONE
Definition: SpellDefines.h:131
@ LOCKTYPE_SLOW_OPEN
Definition: SharedDefines.h:2608

References SpellCastTargets::GetGOTarget(), SpellInfo::Id, LockEntry::Index, Object::IsInWorld(), LOCKTYPE_SLOW_OPEN, m_caster, m_spellInfo, m_targets, prepare(), sLockStore, sSpellMgr, and TRIGGERED_NONE.

Referenced by prepare().

◆ prepare()

SpellCastResult Spell::prepare ( SpellCastTargets const *  targets,
AuraEffect const *  triggeredByAura = nullptr 
)

m_castItemGUID &&

3468{
3469 if (m_CastItem)
3470 {
3472 }
3473 else
3474 {
3476 }
3477
3478 InitExplicitTargets(*targets);
3479
3480 if (!sScriptMgr->CanPrepare(this, targets, triggeredByAura))
3481 {
3482 finish(false);
3483 return SPELL_FAILED_UNKNOWN;
3484 }
3485
3486 // Fill aura scaling information
3488 {
3489 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3490 {
3491 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA ||
3494 {
3495 // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
3497 {
3498 m_auraScaleMask |= (1 << i);
3499 if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints)
3500 {
3501 m_auraScaleMask = 0;
3502 break;
3503 }
3504 }
3505 }
3506 }
3507 }
3508
3510
3511 if (triggeredByAura)
3512 {
3513 m_triggeredByAuraSpell.Init(triggeredByAura);
3514 }
3515
3516 // create and add update event for this spell
3517 _spellEvent = new SpellEvent(this);
3519
3521 {
3523 finish(false);
3525 }
3526
3527 //Prevent casting at cast another spell (ServerSide check)
3529 {
3531 finish(false);
3533 }
3534
3535 LoadScripts();
3536
3537 OnSpellLaunch();
3538
3540
3541 // Set combo point requirement
3543 m_needComboPoints = false;
3544
3545 SpellCastResult result = CheckCast(true);
3546 if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
3547 {
3548 // Periodic auras should be interrupted when aura triggers a spell which can't be cast
3549 // for example bladestorm aura should be removed on disarm as of patch 3.3.5
3550 // channeled periodic spells should be affected by this (arcane missiles, penance, etc)
3551 // a possible alternative sollution for those would be validating aura target on unit state change
3552 if (m_caster->GetTypeId() == TYPEID_PLAYER && triggeredByAura && triggeredByAura->IsPeriodic() && !triggeredByAura->GetBase()->IsPassive())
3553 {
3555 triggeredByAura->GetBase()->SetDuration(0);
3556 }
3557
3558 // Allows to cast melee attack spell if result is SPELL_FAILED_OUT_OF_RANGE
3560 {
3561 SendCastResult(result);
3562
3563 finish(false);
3564 return result;
3565 }
3566 }
3567
3568 // Prepare data for triggers
3569 prepareDataForTriggerSystem(triggeredByAura);
3570
3571 // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
3573
3576 m_casttime = 0;
3577
3578 // don't allow channeled spells / spells with cast time to be casted while moving
3579 // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
3581 {
3582 // 1. Has casttime, 2. Or doesn't have flag to allow action during channel
3584 {
3586 finish(false);
3587 return SPELL_FAILED_MOVING;
3588 }
3589 }
3590
3591 // xinef: if spell have nearby target entry only, do not allow to cast if no targets are found
3592 if (m_CastItem)
3593 {
3594 bool selectTargets = false;
3595 bool nearbyDest = false;
3596
3597 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
3598 {
3599 if (!m_spellInfo->Effects[i].IsEffect())
3600 continue;
3601
3602 if (m_spellInfo->Effects[i].TargetA.GetSelectionCategory() != TARGET_SELECT_CATEGORY_NEARBY || m_spellInfo->Effects[i].TargetA.GetCheckType() != TARGET_CHECK_ENTRY)
3603 {
3604 selectTargets = false;
3605 break;
3606 }
3607
3608 if (m_spellInfo->Effects[i].TargetA.GetObjectType() == TARGET_OBJECT_TYPE_DEST)
3609 {
3610 nearbyDest = true;
3611 }
3612
3613 // xinef: by default set it to false, and to true if any valid target is found
3614 selectTargets = true;
3615 }
3616
3617 if (selectTargets)
3618 {
3620 _spellTargetsSelected = true;
3621 bool spellFailed = false;
3622
3623 if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty())
3624 {
3625 // no valid nearby target unit or game object found; check if nearby destination type
3626 if (nearbyDest)
3627 {
3628 if (!m_targets.HasDst())
3629 {
3630 // no valid target destination
3631 spellFailed = true;
3632 }
3633 }
3634 else
3635 {
3636 spellFailed = true;
3637 }
3638 }
3639
3640 if (spellFailed)
3641 {
3643 finish(false);
3645 }
3646 }
3647 }
3648
3649 // set timer base at cast time
3650 ReSetTimer();
3651
3652 LOG_DEBUG("spells.aura", "Spell::prepare: spell id {} source {} caster {} customCastFlags {} mask {}", m_spellInfo->Id, m_caster->GetEntry(), m_originalCaster ? m_originalCaster->GetEntry() : -1, _triggeredCastFlags, m_targets.GetTargetMask());
3653
3655 {
3657 }
3658
3659 //Containers for channeled spells have to be set
3660 //TODO:Apply this to all casted spells if needed
3661 // Why check duration? 29350: channelled triggers channelled
3663 cast(true);
3664 else
3665 {
3666 // stealth must be removed at cast starting (at show channel bar)
3667 // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
3669 {
3670 // Farsight spells exception
3671 uint32 exceptSpellId = 0;
3673 {
3674 exceptSpellId = m_spellInfo->Id;
3675 }
3676
3679 }
3680
3683
3684 // set target for proper facing
3686 {
3689 {
3690 // Xinef: Creature should focus to cast target if there is explicit target or self if casting positive spell
3691 // Xinef: Creature should not rotate when casting spell... based on halion behavior
3693 }
3694 }
3695
3696 //item: first cast may destroy item and second cast causes crash
3697 // xinef: removed !m_spellInfo->StartRecoveryTime
3698 // second los check failed in events
3699 // xinef: removed itemguid check, currently there is no such item in database
3701 cast(true);
3702
3705 }
3706
3707 return SPELL_CAST_OK;
3708}
@ CHEAT_CASTTIME
Definition: Player.h:999
@ AURA_INTERRUPT_FLAG_SPELL_ATTACK
Definition: SpellDefines.h:57
@ AURA_INTERRUPT_FLAG_CAST
Definition: SpellDefines.h:46
@ TRIGGERED_IGNORE_AURA_SCALING
Will not take away cast item or update related achievement criteria.
Definition: SpellDefines.h:136
@ TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS
In Spell::prepare, will be cast directly without setting containers for executed spell.
Definition: SpellDefines.h:140
@ TRIGGERED_IGNORE_COMBO_POINTS
Will not check if a current cast is in progress.
Definition: SpellDefines.h:138
@ SPELL_INTERRUPT_FLAG_MOVEMENT
Definition: SpellDefines.h:27
@ TARGET_SELECT_CATEGORY_NEARBY
Definition: SpellInfo.h:80
@ TARGET_OBJECT_TYPE_DEST
Definition: SpellInfo.h:100
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
Definition: SharedDefines.h:813
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
Definition: SharedDefines.h:843
@ SPELL_ATTR0_ALLOW_WHILE_SITTING
Definition: SharedDefines.h:409
void FocusTarget(Spell const *focusSpell, WorldObject const *target)
Definition: Creature.cpp:3506
void SetCurrentCastedSpell(Spell *pSpell)
Definition: Unit.cpp:3918
bool IsSitState() const
Definition: Unit.cpp:16626
Definition: Spell.cpp:519
void Init(AuraEffect const *aurEff)
Definition: Spell.cpp:8910
void LoadScripts()
Definition: Spell.cpp:8482
void cast(bool skipCheck=false)
Definition: Spell.cpp:3782
void prepareDataForTriggerSystem(AuraEffect const *triggeredByAura)
Definition: Spell.cpp:2291
void SendSpellStart()
Definition: Spell.cpp:4703
void TriggerGlobalCooldown()
Definition: Spell.cpp:8826
void OnSpellLaunch()
Definition: Spell.cpp:8887
CurrentSpellTypes GetCurrentContainer() const
Definition: Spell.cpp:7897
void ReSetTimer()
Definition: Spell.h:550
void InitExplicitTargets(SpellCastTargets const &targets)
Definition: Spell.cpp:713
bool IsActionAllowedChannel() const
Definition: SpellInfo.cpp:1260
int32 GetMaxDuration() const
Definition: SpellInfo.cpp:2344
uint32 Attributes
Definition: SpellInfo.h:324
bool IsBreakingStealth() const
Definition: SpellInfo.cpp:1270

References _spellEvent, _spellTargetsSelected, _triggeredCastFlags, EventProcessor::AddEvent(), SpellInfo::Attributes, AURA_INTERRUPT_FLAG_CAST, AURA_INTERRUPT_FLAG_NOT_SEATED, AURA_INTERRUPT_FLAG_SPELL_ATTACK, SpellInfo::AuraInterruptFlags, SpellInfo::CalcCastTime(), SpellInfo::CalcPowerCost(), EventProcessor::CalculateTime(), cast(), CHEAT_CASTTIME, CheckCast(), CURRENT_GENERIC_SPELL, DISABLE_TYPE_SPELL, EFFECT_0, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, finish(), Creature::FocusTarget(), AuraEffect::GetBase(), Player::GetCommandStatus(), GetCurrentContainer(), Object::GetEntry(), Object::GetGUID(), SpellInfo::GetMaxDuration(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetTargetMask(), Object::GetTypeId(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasTriggeredCastFlag(), SpellInfo::Id, TriggeredByAuraSpellData::Init(), InitExplicitTargets(), SpellInfo::InterruptFlags, SpellInfo::IsActionAllowedChannel(), IsAutoRepeat(), SpellInfo::IsBreakingStealth(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), DisableMgr::IsDisabledFor(), Creature::IsInEvadeMode(), Unit::isMoving(), IsNextMeleeSwingSpell(), Unit::IsNonMeleeSpellCast(), Aura::IsPassive(), SpellInfo::IsPassive(), AuraEffect::IsPeriodic(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsSitState(), Unit::IsTotem(), IsTriggered(), LoadScripts(), LOG_DEBUG, m_auraScaleMask, m_cast_count, m_caster, m_CastItem, m_castItemGUID, m_casttime, Unit::m_Events, m_needComboPoints, m_originalCaster, m_powerCost, m_spellInfo, m_spellSchoolMask, m_spellState, m_spellValue, m_targets, m_triggeredByAuraSpell, m_UniqueGOTargetInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, OnSpellLaunch(), prepareDataForTriggerSystem(), Unit::RemoveAurasWithInterruptFlags(), ReSetTimer(), SelectSpellTargets(), SendCastResult(), SendChannelUpdate(), SendSpellStart(), Unit::SetCurrentCastedSpell(), Aura::SetDuration(), Unit::SetStandState(), SPELL_ATTR0_ALLOW_WHILE_SITTING, SPELL_CAST_OK, SPELL_EFFECT_ADD_FARSIGHT, SPELL_EFFECT_APPLY_AREA_AURA_PARTY, SPELL_EFFECT_APPLY_AREA_AURA_RAID, SPELL_EFFECT_APPLY_AURA, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_MOVING, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_SPELL_IN_PROGRESS, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_UNKNOWN, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_PREPARING, SpellInfo::SpellLevel, sScriptMgr, TARGET_CHECK_ENTRY, TARGET_OBJECT_TYPE_DEST, TARGET_SELECT_CATEGORY_NEARBY, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS, TRIGGERED_IGNORE_AURA_SCALING, TRIGGERED_IGNORE_CAST_IN_PROGRESS, TRIGGERED_IGNORE_COMBO_POINTS, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_SET_FACING, TriggerGlobalCooldown(), TYPEID_PLAYER, TYPEID_UNIT, and UNIT_STAND_STATE_STAND.

Referenced by Unit::_UpdateAutoRepeatSpell(), Player::CastItemUseSpell(), Unit::CastSpell(), EffectEnchantItemTmp(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandleCastSpellOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), OnSpellLaunch(), and PetAI::UpdateAI().

◆ prepareDataForTriggerSystem()

void Spell::prepareDataForTriggerSystem ( AuraEffect const *  triggeredByAura)
protected
2292{
2293 //==========================================================================================
2294 // Now fill data for trigger system, need know:
2295 // can spell trigger another or not (m_canTrigger)
2296 // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_procEx)
2297 //==========================================================================================
2298
2300 // Get data for type of attack and fill base info for trigger
2301 switch (m_spellInfo->DmgClass)
2302 {
2305 if (m_attackType == OFF_ATTACK)
2307 else
2310 break;
2312 // Auto attack
2314 {
2317 }
2318 else // Ranged spell attack
2319 {
2322 }
2323 break;
2324 default:
2327 && m_spellInfo->HasAttribute(SPELL_ATTR2_AUTO_REPEAT)) // Wands auto attack
2328 {
2331 }
2332 // For other spells trigger procflags are set in Spell::DoAllEffectOnTarget
2333 // Because spell positivity is dependant on target
2334 }
2336
2337 // Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection
2339 (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow
2340 m_spellInfo->Id == 57879 || m_spellInfo->Id == 45145 || // Snake Trap - done this way to avoid double proc
2341 m_spellInfo->SpellFamilyFlags[2] & 0x00064000)) // Explosive and Immolation Trap
2342 {
2344 }
2345
2346 /* Effects which are result of aura proc from triggered spell cannot proc
2347 to prevent chain proc of these spells */
2348
2349 // Hellfire Effect - trigger as DOT
2351 {
2354 }
2355
2356 // Ranged autorepeat attack is set as triggered spell - ignore it
2358 {
2365 }
2366 // Totem casts require spellfamilymask defined in spell_proc_event to proc
2369}
@ TRIGGERED_DISALLOW_PROC_EVENTS
Will ignore caster aura restrictions or requirements.
Definition: SpellDefines.h:146
@ PROC_EX_NONE
Definition: SpellMgr.h:193
@ PROC_EX_INTERNAL_CANT_PROC
Definition: SpellMgr.h:218
@ PROC_EX_INTERNAL_TRIGGERED
Definition: SpellMgr.h:221
@ PROC_EX_INTERNAL_REQ_FAMILY
Definition: SpellMgr.h:222
@ PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS
Definition: SpellMgr.h:119
@ PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK
Definition: SpellMgr.h:117
@ PROC_FLAG_DONE_PERIODIC
Definition: SpellMgr.h:134
@ PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS
Definition: SpellMgr.h:113
@ PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS
Definition: SpellMgr.h:120
@ PROC_FLAG_TAKEN_PERIODIC
Definition: SpellMgr.h:135
@ PROC_FLAG_DONE_MAINHAND_ATTACK
Definition: SpellMgr.h:140
@ PROC_FLAG_DONE_RANGED_AUTO_ATTACK
Definition: SpellMgr.h:116
@ PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS
Definition: SpellMgr.h:114
@ PROC_FLAG_DONE_TRAP_ACTIVATION
Definition: SpellMgr.h:138
@ PROC_FLAG_DONE_OFFHAND_ATTACK
Definition: SpellMgr.h:141
@ SPELL_ATTR2_ACTIVE_THREAT
Definition: SharedDefines.h:486
@ SPELL_ATTR3_NOT_A_PROC
Definition: SharedDefines.h:502

References SpellInfo::DmgClass, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Object::GetTypeId(), SpellInfo::HasAttribute(), HasTriggeredCastFlag(), SpellInfo::Id, Unit::IsControlledByPlayer(), Unit::IsTotem(), ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_spellInfo, OFF_ATTACK, PROC_EX_INTERNAL_CANT_PROC, PROC_EX_INTERNAL_REQ_FAMILY, PROC_EX_INTERNAL_TRIGGERED, PROC_EX_NONE, PROC_FLAG_DONE_MAINHAND_ATTACK, PROC_FLAG_DONE_OFFHAND_ATTACK, PROC_FLAG_DONE_PERIODIC, PROC_FLAG_DONE_RANGED_AUTO_ATTACK, PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS, PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS, PROC_FLAG_DONE_TRAP_ACTIVATION, PROC_FLAG_TAKEN_PERIODIC, PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK, PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS, PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS, SPELL_ATTR2_ACTIVE_THREAT, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_NOT_A_PROC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLFAMILY_HUNTER, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Object::ToCreature(), TRIGGERED_DISALLOW_PROC_EVENTS, and TYPEID_UNIT.

Referenced by prepare().

◆ PrepareScriptHitHandlers()

void Spell::PrepareScriptHitHandlers ( )
protected
8563{
8564 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8565 (*scritr)->_InitHit();
8566}

References m_loadedScripts.

Referenced by _cast(), _handle_immediate_phase(), and DoAllEffectOnTarget().

◆ PrepareTargetProcessing()

void Spell::PrepareTargetProcessing ( )
protected

◆ PrepareTriggersExecutedOnHit()

void Spell::PrepareTriggersExecutedOnHit ( )
protected
Todo:
: move this to scripts
Todo:
: move this to scripts
8737{
8740 {
8741 SpellInfo const* excludeCasterSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeCasterAuraSpell);
8742 if (excludeCasterSpellInfo && !excludeCasterSpellInfo->IsPositive())
8744 SpellInfo const* excludeTargetSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeTargetAuraSpell);
8745 if (excludeTargetSpellInfo && !excludeTargetSpellInfo->IsPositive())
8747 }
8748
8751 {
8753 {
8754 if( m_spellInfo->SpellFamilyFlags[1] & 0x40000000 )
8755 {
8757 for(Unit::AuraEffectList::const_iterator itr = mVindication.begin(); itr != mVindication.end(); ++itr)
8758 {
8759 if( (*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 26017 )
8760 {
8761 m_preCastSpell = 26017;
8762 break;
8763 }
8764 else if( (*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 67 )
8765 m_preCastSpell = 67;
8766 }
8767 }
8768 break;
8769 }
8770 case SPELLFAMILY_DRUID:
8771 {
8772 // Faerie Fire (Feral)
8774 m_preCastSpell = 60089;
8775
8776 break;
8777 }
8778 }
8779
8780 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras:
8781 // save auras which were present on spell caster on cast, to prevent triggered auras from affecting caster
8782 // and to correctly calculate proc chance when combopoints are present
8784 for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
8785 {
8786 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
8787 continue;
8788 SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo();
8789 uint32 auraSpellIdx = (*i)->GetEffIndex();
8790 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraSpellInfo->Effects[auraSpellIdx].TriggerSpell))
8791 {
8792 // calculate the chance using spell base amount, because aura amount is not updated on combo-points change
8793 // this possibly needs fixing
8794 int32 auraBaseAmount = (*i)->GetBaseAmount();
8795 // proc chance is stored in effect amount
8796 int32 chance = m_caster->CalculateSpellDamage(nullptr, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
8797 // build trigger and add to the list
8798 HitTriggerSpell spellTriggerInfo;
8799 spellTriggerInfo.triggeredSpell = spellInfo;
8800 spellTriggerInfo.triggeredByAura = auraSpellInfo;
8801 spellTriggerInfo.triggeredByEffIdx = (*i)->GetEffIndex();
8802 spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount();
8803 m_hitTriggerSpells.push_back(spellTriggerInfo);
8804 }
8805 }
8806}
@ FORM_DIREBEAR
Definition: UnitDefines.h:77
@ FORM_BEAR
Definition: UnitDefines.h:74
@ SPELL_AURA_PROC_TRIGGER_SPELL
Definition: SpellAuraDefines.h:105
@ SPELL_AURA_ADD_TARGET_TRIGGER
Definition: SpellAuraDefines.h:172
uint32 ExcludeTargetAuraSpell
Definition: SpellInfo.h:346

References Unit::CalculateSpellDamage(), Spell::HitTriggerSpell::chance, EFFECT_0, SpellInfo::Effects, SpellInfo::ExcludeCasterAuraSpell, SpellInfo::ExcludeTargetAuraSpell, FORM_BEAR, FORM_DIREBEAR, Unit::GetAuraEffectsByType(), Unit::GetShapeshiftForm(), SpellInfo::Id, SpellInfo::IsPositive(), m_caster, m_hitTriggerSpells, m_preCastSpell, m_spellInfo, SPELL_AURA_ADD_TARGET_TRIGGER, SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_DRUID, SPELLFAMILY_PALADIN, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, sSpellMgr, Spell::HitTriggerSpell::triggeredByAura, Spell::HitTriggerSpell::triggeredByEffIdx, and Spell::HitTriggerSpell::triggeredSpell.

Referenced by _cast().

◆ RecalculateDelayMomentForDst()

void Spell::RecalculateDelayMomentForDst ( )
917{
920}
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:27
void ModifyEventTime(BasicEvent *event, Milliseconds newTime)
Definition: EventProcessor.cpp:145
uint64 CalculateDelayMomentForDst() const
Definition: Spell.cpp:895
uint64 GetDelayStart() const
Definition: Spell.h:562

References _spellEvent, CalculateDelayMomentForDst(), GetDelayStart(), m_caster, m_delayMoment, Unit::m_Events, and EventProcessor::ModifyEventTime().

◆ ReSetTimer()

void Spell::ReSetTimer ( )
inline
550{ m_timer = m_casttime > 0 ? m_casttime : 0; }

References m_casttime, and m_timer.

Referenced by prepare().

◆ SearchAreaTargets()

void Spell::SearchAreaTargets ( std::list< WorldObject * > &  targets,
float  range,
Position const *  position,
Unit referer,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList condList 
)
2186{
2187 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2188 if (!containerTypeMask)
2189 return;
2190 Acore::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList);
2191 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
2192 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, position, range);
2193}
Definition: GridNotifiers.h:239
uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList *condList)
Definition: Spell.cpp:2109

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SearchChainTargets(), and SelectImplicitAreaTargets().

◆ SearchChainTargets()

void Spell::SearchChainTargets ( std::list< WorldObject * > &  targets,
uint32  chainTargets,
WorldObject target,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectType,
SpellTargetSelectionCategories  selectCategory,
ConditionList condList,
bool  isChainHeal 
)
2196{
2197 // max dist for jump target selection
2198 float jumpRadius = 0.0f;
2199 switch (m_spellInfo->DmgClass)
2200 {
2202 // 7.5y for multi shot
2203 jumpRadius = 7.5f;
2204 break;
2206 // 5y for swipe, cleave and similar
2207 jumpRadius = 5.0f;
2208 break;
2211 // 12.5y for chain heal spell since 3.2 patch
2212 if (isChainHeal)
2213 jumpRadius = 12.5f;
2214 // 10y as default for magic chain spells
2215 else
2216 jumpRadius = 10.0f;
2217 break;
2218 }
2219
2220 // chain lightning/heal spells and similar - allow to jump at larger distance and go out of los
2224
2225 // max dist which spell can reach
2226 float searchRadius = jumpRadius;
2227 if (isBouncingFar)
2228 searchRadius *= chainTargets;
2229
2230 std::list<WorldObject*> tempTargets;
2231 SearchAreaTargets(tempTargets, searchRadius, target, m_caster, objectType, selectType, condList);
2232 tempTargets.remove(target);
2233
2234 // remove targets which are always invalid for chain spells
2235 // for some spells allow only chain targets in front of caster (swipe for example)
2236 if (!isBouncingFar)
2237 {
2238 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end();)
2239 {
2240 std::list<WorldObject*>::iterator checkItr = itr++;
2241 if (!m_caster->HasInArc(static_cast<float>(M_PI), *checkItr))
2242 tempTargets.erase(checkItr);
2243 }
2244 }
2245
2246 while (chainTargets)
2247 {
2248 // try to get unit for next chain jump
2249 std::list<WorldObject*>::iterator foundItr = tempTargets.end();
2250 // get unit with highest hp deficit in dist
2251 if (isChainHeal)
2252 {
2253 uint32 maxHPDeficit = 0;
2254 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2255 {
2256 if (Unit* unit = (*itr)->ToUnit())
2257 {
2258 uint32 deficit = unit->GetMaxHealth() - unit->GetHealth();
2259 if ((deficit > maxHPDeficit || foundItr == tempTargets.end()) && target->IsWithinDist(unit, jumpRadius) && target->IsWithinLOSInMap(unit, VMAP::ModelIgnoreFlags::M2))
2260 {
2261 foundItr = itr;
2262 maxHPDeficit = deficit;
2263 }
2264 }
2265 }
2266 }
2267 // get closest object
2268 else
2269 {
2270 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2271 {
2272 if (foundItr == tempTargets.end())
2273 {
2274 if ((!isBouncingFar || target->IsWithinDist(*itr, jumpRadius)) && target->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2275 foundItr = itr;
2276 }
2277 else if (target->GetDistanceOrder(*itr, *foundItr) && target->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2278 foundItr = itr;
2279 }
2280 }
2281 // not found any valid target - chain ends
2282 if (foundItr == tempTargets.end())
2283 break;
2284 target = *foundItr;
2285 tempTargets.erase(foundItr);
2286 targets.push_back(target);
2287 --chainTargets;
2288 }
2289}
@ SPELL_ATTR4_BOUNCY_CHAIN_MISSILES
Definition: SharedDefines.h:548
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
Definition: Object.cpp:1316
bool GetDistanceOrder(WorldObject const *obj1, WorldObject const *obj2, bool is3D=true) const
Definition: Object.cpp:1381
void SearchAreaTargets(std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList)
Definition: Spell.cpp:2185

References SpellInfo::DmgClass, WorldObject::GetDistanceOrder(), SpellInfo::HasAttribute(), Position::HasInArc(), WorldObject::IsWithinDist(), WorldObject::IsWithinLOSInMap(), VMAP::M2, m_caster, m_spellInfo, SearchAreaTargets(), SPELL_ATTR4_BOUNCY_CHAIN_MISSILES, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_NONE, SPELL_DAMAGE_CLASS_RANGED, and Object::ToUnit().

Referenced by SelectImplicitChainTargets().

◆ SearchNearbyTarget()

WorldObject * Spell::SearchNearbyTarget ( float  range,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList condList = nullptr 
)
2174{
2175 WorldObject* target = nullptr;
2176 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2177 if (!containerTypeMask)
2178 return nullptr;
2179 Acore::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList);
2181 SearchTargets<Acore::WorldObjectLastSearcher<Acore::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
2182 return target;
2183}
Definition: GridNotifiers.h:219

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SelectImplicitNearbyTargets().

◆ SearchTargets()

template<class SEARCHER >
void Spell::SearchTargets ( SEARCHER &  searcher,
uint32  containerMask,
Unit referer,
Position const *  pos,
float  radius 
)
2145{
2146 if (!containerMask)
2147 return;
2148
2149 // search world and grid for possible targets
2150 bool searchInGrid = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_GAMEOBJECT);
2151 bool searchInWorld = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER | GRID_MAP_TYPE_MASK_CORPSE);
2152
2153 if (searchInGrid || searchInWorld)
2154 {
2155 float x, y;
2156 x = pos->GetPositionX();
2157 y = pos->GetPositionY();
2158
2160 Cell cell(p);
2161 cell.SetNoCreate();
2162
2163 Map* map = referer->GetMap();
2164
2165 if (searchInWorld)
2166 Cell::VisitWorldObjects(x, y, map, searcher, radius);
2167
2168 if (searchInGrid)
2169 Cell::VisitGridObjects(x, y, map, searcher, radius);
2170 }
2171}
static void VisitGridObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:179

References Acore::ComputeCellCoord(), WorldObject::GetMap(), Position::GetPositionX(), Position::GetPositionY(), GRID_MAP_TYPE_MASK_CORPSE, GRID_MAP_TYPE_MASK_CREATURE, GRID_MAP_TYPE_MASK_GAMEOBJECT, GRID_MAP_TYPE_MASK_PLAYER, Cell::SetNoCreate(), Cell::VisitGridObjects(), and Cell::VisitWorldObjects().

◆ SelectEffectImplicitTargets()

void Spell::SelectEffectImplicitTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32 processedEffectMask 
)
923{
924 if (!targetType.GetTarget())
925 return;
926
927 uint32 effectMask = 1 << effIndex;
928 // set the same target list for all effects
929 // some spells appear to need this, however this requires more research
930 switch (targetType.GetSelectionCategory())
931 {
935 {
936 // targets for effect already selected
937 if (effectMask & processedEffectMask)
938 {
939 return;
940 }
941
942 auto const& effects = GetSpellInfo()->Effects;
943
944 // choose which targets we can select at once
945 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
946 {
947 if (effects[j].IsEffect() &&
948 effects[effIndex].TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
949 effects[effIndex].TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
950 effects[effIndex].ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
951 effects[effIndex].CalcRadius(m_caster) == effects[j].CalcRadius(m_caster) &&
953 {
954 effectMask |= 1 << j;
955 }
956 }
957 processedEffectMask |= effectMask;
958 break;
959 }
960 default:
961 break;
962 }
963
964 switch (targetType.GetSelectionCategory())
965 {
967 SelectImplicitChannelTargets(effIndex, targetType);
968 break;
970 SelectImplicitNearbyTargets(effIndex, targetType, effectMask);
971 break;
973 SelectImplicitConeTargets(effIndex, targetType, effectMask);
974 break;
976 SelectImplicitAreaTargets(effIndex, targetType, effectMask);
977 break;
979 // just in case there is no dest, explanation in SelectImplicitDestDestTargets
980 CheckDst();
981
982 SelectImplicitTrajTargets(effIndex, targetType);
983 break;
985 switch (targetType.GetObjectType())
986 {
988 switch (targetType.GetReferenceType())
989 {
992 break;
993 default:
994 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_SRC");
995 break;
996 }
997 break;
999 switch (targetType.GetReferenceType())
1000 {
1002 SelectImplicitCasterDestTargets(effIndex, targetType);
1003 break;
1005 SelectImplicitTargetDestTargets(effIndex, targetType);
1006 break;
1008 SelectImplicitDestDestTargets(effIndex, targetType);
1009 break;
1010 default:
1011 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
1012 break;
1013 }
1014 break;
1015 default:
1016 switch (targetType.GetReferenceType())
1017 {
1019 SelectImplicitCasterObjectTargets(effIndex, targetType);
1020 break;
1022 SelectImplicitTargetObjectTargets(effIndex, targetType);
1023 break;
1024 default:
1025 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
1026 break;
1027 }
1028 break;
1029 }
1030 break;
1032 LOG_DEBUG("spells.aura", "SPELL: target type {}, found in spellID {}, effect {} is not implemented yet!", m_spellInfo->Id, effIndex, targetType.GetTarget());
1033 break;
1034 default:
1035 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target category");
1036 break;
1037 }
1038}
@ TARGET_SELECT_CATEGORY_CONE
Definition: SpellInfo.h:81
@ TARGET_SELECT_CATEGORY_AREA
Definition: SpellInfo.h:82
@ TARGET_SELECT_CATEGORY_DEFAULT
Definition: SpellInfo.h:78
@ TARGET_SELECT_CATEGORY_NYI
Definition: SpellInfo.h:77
@ TARGET_SELECT_CATEGORY_TRAJ
Definition: SpellInfo.h:83
@ TARGET_SELECT_CATEGORY_CHANNEL
Definition: SpellInfo.h:79
@ TARGET_OBJECT_TYPE_SRC
Definition: SpellInfo.h:99
@ TARGET_REFERENCE_TYPE_TARGET
Definition: SpellInfo.h:90
@ TARGET_REFERENCE_TYPE_CASTER
Definition: SpellInfo.h:89
@ TARGET_REFERENCE_TYPE_DEST
Definition: SpellInfo.h:93
void SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1717
void CheckDst()
Definition: Spell.h:492
void SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1866
void SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1210
void SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1680
void SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1260
void SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1040
void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1803
void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1756
void SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1096
bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
Definition: Spell.cpp:8697
void SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1342

References ASSERT, CheckDst(), CheckScriptEffectImplicitTargets(), SpellInfo::Effects, SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellImplicitTargetInfo::GetSelectionCategory(), GetSpellInfo(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::Id, LOG_DEBUG, m_caster, m_spellInfo, m_targets, MAX_SPELL_EFFECTS, SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTargetObjectTargets(), SelectImplicitTrajTargets(), SpellCastTargets::SetSrc(), TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_SRC, TARGET_REFERENCE_TYPE_CASTER, TARGET_REFERENCE_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CATEGORY_CHANNEL, TARGET_SELECT_CATEGORY_CONE, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CATEGORY_NEARBY, TARGET_SELECT_CATEGORY_NYI, and TARGET_SELECT_CATEGORY_TRAJ.

Referenced by SelectSpellTargets().

◆ SelectEffectTypeImplicitTargets()

void Spell::SelectEffectTypeImplicitTargets ( uint8  effIndex)
Todo:
: this is a workaround - target shouldn't be stored in target map for those spells
Todo:
: this is a workaround - corpses should be added to spell target map too, but we can't do that so we add owner instead
2027{
2028 // special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
2030 switch (m_spellInfo->Effects[effIndex].Effect)
2031 {
2035 {
2037
2039
2040 if (target && target->ToPlayer())
2041 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2042 }
2043 return;
2044 default:
2045 break;
2046 }
2047
2048 // select spell implicit targets based on effect type
2049 if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2050 return;
2051
2052 uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask();
2053
2054 if (!targetMask)
2055 return;
2056
2057 WorldObject* target = nullptr;
2058
2059 switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2060 {
2061 // add explicit object target or self to the target map
2063 // player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK
2065 {
2067 target = unitTarget;
2068 else if (targetMask & TARGET_FLAG_CORPSE_MASK)
2069 {
2070 if (Corpse* corpseTarget = m_targets.GetCorpseTarget())
2071 {
2073 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
2074 target = owner;
2075 }
2076 }
2077 else //if (targetMask & TARGET_FLAG_UNIT_MASK)
2078 target = m_caster;
2079 }
2080 if (targetMask & TARGET_FLAG_ITEM_MASK)
2081 {
2083 AddItemTarget(itemTarget, 1 << effIndex);
2084 return;
2085 }
2086 if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK)
2087 target = m_targets.GetGOTarget();
2088 break;
2089 // add self to the target map
2091 if (targetMask & TARGET_FLAG_UNIT_MASK)
2092 target = m_caster;
2093 break;
2094 default:
2095 break;
2096 }
2097
2099
2100 if (target)
2101 {
2102 if (target->ToUnit())
2103 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2104 else if (target->ToGameObject())
2105 AddGOTarget(target->ToGameObject(), 1 << effIndex);
2106 }
2107}
@ EFFECT_IMPLICIT_TARGET_CASTER
Definition: SpellInfo.h:144
@ EFFECT_IMPLICIT_TARGET_EXPLICIT
Definition: SpellInfo.h:143
@ TARGET_FLAG_ITEM_MASK
Definition: SpellInfo.h:72
GameObject * ToGameObject()
Definition: Object.h:205
Corpse * GetCorpseTarget() const
Definition: Spell.cpp:294
void AddGOTarget(GameObject *target, uint32 effectMask)
Definition: Spell.cpp:2513
void AddUnitTarget(Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
Definition: Spell.cpp:2380
void AddItemTarget(Item *item, uint32 effectMask)
Definition: Spell.cpp:2575
void CallScriptObjectTargetSelectHandlers(WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8669
Definition: SpellInfo.h:217

References AddGOTarget(), AddItemTarget(), AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), EFFECT_IMPLICIT_TARGET_CASTER, EFFECT_IMPLICIT_TARGET_EXPLICIT, SpellInfo::Effects, ObjectAccessor::FindPlayer(), SpellCastTargets::GetCorpseTarget(), SpellCastTargets::GetGOTarget(), SpellCastTargets::GetItemTarget(), Unit::GetTarget(), Object::GetTypeId(), SpellCastTargets::GetUnitTarget(), itemTarget, m_caster, m_spellInfo, m_targets, SPELL_EFFECT_SUMMON_PLAYER, SPELL_EFFECT_SUMMON_RAF_FRIEND, TARGET_FLAG_CORPSE_MASK, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_ITEM_MASK, TARGET_FLAG_UNIT_MASK, Object::ToGameObject(), Object::ToPlayer(), Object::ToUnit(), TYPEID_PLAYER, and unitTarget.

Referenced by SelectSpellTargets().

◆ SelectExplicitTargets()

void Spell::SelectExplicitTargets ( )
783{
784 // here go all explicit target changes made to explicit targets after spell prepare phase is finished
785 if (Unit* target = m_targets.GetUnitTarget())
786 {
787 // check for explicit target redirection, for Grounding Totem for example
791 {
792 Unit* redirect;
793 switch (m_spellInfo->DmgClass)
794 {
797 break;
801 break;
802 default:
803 redirect = nullptr;
804 break;
805 }
806 if (redirect && (redirect != target))
807 {
808 m_targets.SetUnitTarget(redirect);
810 }
811 }
812 }
813}
Unit * GetMeleeHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo=nullptr)
Definition: Unit.cpp:10979
Unit * GetMagicHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition: Unit.cpp:10941

References SpellInfo::DmgClass, SpellInfo::GetExplicitTargetMask(), Unit::GetMagicHitRedirectTarget(), Unit::GetMeleeHitRedirectTarget(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasEffect(), Unit::IsFriendlyTo(), SpellInfo::IsPositive(), m_caster, m_spellFlags, m_spellInfo, m_targets, SpellCastTargets::SetUnitTarget(), SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_DISPEL, SPELL_FLAG_REDIRECTED, TARGET_FLAG_UNIT, and TARGET_FLAG_UNIT_ENEMY.

Referenced by SelectSpellTargets().

◆ SelectImplicitAreaTargets()

void Spell::SelectImplicitAreaTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1261{
1262 Unit* referer = nullptr;
1263 switch (targetType.GetReferenceType())
1264 {
1268 referer = m_caster;
1269 break;
1271 referer = m_targets.GetUnitTarget();
1272 break;
1274 {
1275 // find last added target for this effect
1276 for (std::list<TargetInfo>::reverse_iterator ihit = m_UniqueTargetInfo.rbegin(); ihit != m_UniqueTargetInfo.rend(); ++ihit)
1277 {
1278 if (ihit->effectMask & (1 << effIndex))
1279 {
1280 referer = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
1281 break;
1282 }
1283 }
1284 break;
1285 }
1286 default:
1287 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1288 return;
1289 }
1290 if (!referer)
1291 return;
1292
1293 Position const* center = nullptr;
1294 switch (targetType.GetReferenceType())
1295 {
1297 center = m_targets.GetSrcPos();
1298 break;
1300 center = m_targets.GetDstPos();
1301 break;
1305 center = referer;
1306 break;
1307 default:
1308 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1309 return;
1310 }
1311
1312 // Xinef: the distance should be increased by caster size, it is neglected in latter calculations
1313 std::list<WorldObject*> targets;
1314 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1315 SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1316
1317 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1318
1319 if (!targets.empty())
1320 {
1321 // Other special target selection goes here
1322 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1323 {
1325 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
1326 if ((*j)->IsAffectedOnSpell(m_spellInfo))
1327 maxTargets += (*j)->GetAmount();
1328
1329 Acore::Containers::RandomResize(targets, maxTargets);
1330 }
1331
1332 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1333 {
1334 if (Unit* unitTarget = (*itr)->ToUnit())
1335 AddUnitTarget(unitTarget, effMask, false);
1336 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1337 AddGOTarget(gObjTarget, effMask);
1338 }
1339 }
1340}
@ SPELL_AURA_MOD_MAX_AFFECTED_TARGETS
Definition: SpellAuraDefines.h:340
@ TARGET_REFERENCE_TYPE_SRC
Definition: SpellInfo.h:92
@ TARGET_REFERENCE_TYPE_LAST
Definition: SpellInfo.h:91
void RandomResize(C &container, std::size_t requestedSize)
Definition: Containers.h:79
Position const * GetSrcPos() const
Definition: Spell.cpp:362
float RadiusMod
Definition: Spell.h:215
uint32 MaxAffectedTargets
Definition: Spell.h:214
void CallScriptObjectAreaTargetSelectHandlers(std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8655

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, Unit::GetAuraEffectsByType(), SpellImplicitTargetInfo::GetCheckType(), SpellCastTargets::GetDstPos(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetSrcPos(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTarget(), m_caster, m_spellInfo, m_spellValue, m_targets, m_UniqueTargetInfo, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, Acore::Containers::RandomResize(), SearchAreaTargets(), SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, TARGET_REFERENCE_TYPE_CASTER, TARGET_REFERENCE_TYPE_DEST, TARGET_REFERENCE_TYPE_LAST, TARGET_REFERENCE_TYPE_SRC, TARGET_REFERENCE_TYPE_TARGET, Object::ToGameObject(), Object::ToUnit(), and unitTarget.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterDestTargets()

void Spell::SelectImplicitCasterDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
Todo:
fix this check
1343{
1345
1346 switch (targetType.GetTarget())
1347 {
1348 case TARGET_DEST_CASTER:
1350 break;
1351 case TARGET_DEST_HOME:
1352 if (Player* playerCaster = m_caster->ToPlayer())
1353 dest = SpellDestination(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId);
1354 break;
1355 case TARGET_DEST_DB:
1356 if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex))
1357 {
1360 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
1361 else if (st->target_mapId == m_caster->GetMapId())
1362 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
1363 }
1364 else
1365 {
1366 LOG_DEBUG("spells.aura", "SPELL: unknown target coordinates for spell ID {}", m_spellInfo->Id);
1367 if (WorldObject* target = m_targets.GetObjectTarget())
1368 dest = SpellDestination(*target);
1369 }
1370 break;
1372 {
1373 float min_dis = m_spellInfo->GetMinRange(true);
1374 float max_dis = m_spellInfo->GetMaxRange(true);
1375 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
1376 float x, y, z, angle;
1377 angle = (float)rand_norm() * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
1378 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle); this contains extra code that breaks fishing
1380
1381 float ground = m_caster->GetMapHeight(x, y, z, true);
1382 float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
1384 if (liquidData.Status)
1385 liquidLevel = liquidData.Level;
1386
1387 if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level
1388 {
1391 finish(false);
1392 return;
1393 }
1394
1395 if (ground + 0.75 > liquidLevel)
1396 {
1399 finish(false);
1400 return;
1401 }
1402
1403 if (!m_caster->IsWithinLOS(x, y, z))
1404 {
1407 finish(false);
1408 return;
1409 }
1410
1411 dest = SpellDestination(x, y, liquidLevel, m_caster->GetOrientation());
1412 break;
1413 }
1415 {
1416 float distance = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1417 Map* map = m_caster->GetMap();
1418 uint32 mapid = m_caster->GetMapId();
1419 uint32 phasemask = m_caster->GetPhaseMask();
1420 float collisionHeight = m_caster->GetCollisionHeight();
1421 float destz = 0.0f, startx = 0.0f, starty = 0.0f, startz = 0.0f, starto = 0.0f;
1422
1423 Position pos;
1424 Position lastpos;
1425 m_caster->GetPosition(startx, starty, startz, starto);
1426 pos.Relocate(startx, starty, startz, starto);
1427 float destx = pos.GetPositionX() + distance * cos(pos.GetOrientation());
1428 float desty = pos.GetPositionY() + distance * sin(pos.GetOrientation());
1429
1430 float ground = map->GetHeight(phasemask, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
1431
1432 bool isCasterInWater = m_caster->IsInWater();
1433 if (!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) || (pos.GetPositionZ() - ground < distance))
1434 {
1435 float tstX = 0.0f, tstY = 0.0f, tstZ = 0.0f, prevX = 0.0f, prevY = 0.0f, prevZ = 0.0f;
1436 float tstZ1 = 0.0f, tstZ2 = 0.0f, tstZ3 = 0.0f, destz1 = 0.0f, destz2 = 0.0f, destz3 = 0.0f, srange = 0.0f, srange1 = 0.0f, srange2 = 0.0f, srange3 = 0.0f;
1437 float maxtravelDistZ = 2.65f;
1438 float overdistance = 0.0f;
1439 float totalpath = 0.0f;
1440 float beforewaterz = 0.0f;
1441 bool inwater = false;
1442 bool wcol = false;
1443 const float step = 2.0f;
1444 const uint8 numChecks = ceil(fabs(distance / step));
1445 const float DELTA_X = (destx - pos.GetPositionX()) / numChecks;
1446 const float DELTA_Y = (desty - pos.GetPositionY()) / numChecks;
1447 int j = 1;
1448 for (; j < (numChecks + 1); j++)
1449 {
1450 prevX = pos.GetPositionX() + (float(j - 1) * DELTA_X);
1451 prevY = pos.GetPositionY() + (float(j - 1) * DELTA_Y);
1452 tstX = pos.GetPositionX() + (float(j) * DELTA_X);
1453 tstY = pos.GetPositionY() + (float(j) * DELTA_Y);
1454
1455 if (j < 2)
1456 {
1457 prevZ = pos.GetPositionZ();
1458 }
1459 else
1460 {
1461 prevZ = tstZ;
1462 }
1463
1464 tstZ = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true);
1465 ground = tstZ;
1466
1467 if (!isCasterInWater)
1468 {
1469 if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1470 {
1471 if (!(beforewaterz != 0.0f))
1472 {
1473 beforewaterz = prevZ;
1474 }
1475 tstZ = beforewaterz;
1476 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1477 //LOG_ERROR("spells", "(start was from land) step in water , number of cycle = {} , distance of step = {}, total path = {}, Z = {}", j, srange, totalpath, tstZ);
1478 }
1479 }
1480 else if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1481 {
1482 prevZ = pos.GetPositionZ();
1483 tstZ = pos.GetPositionZ();
1484 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1485
1486 inwater = true;
1487 if (inwater && (fabs(tstZ - ground) < 2.0f))
1488 {
1489 wcol = true;
1490 //LOG_ERROR("spells", "step in water with collide and use standart check (for continue way after possible collide), number of cycle = {} ", j);
1491 }
1492
1493 // if (j < 2)
1494 // LOG_ERROR("spells", "(start in water) step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1495 // else
1496 // LOG_ERROR("spells", "step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1497 }
1498
1499 bool IsInWater = map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight);
1500 if ((!IsInWater && tstZ != beforewaterz) || wcol) // second safety check z for blink way if on the ground
1501 {
1502 if (inwater && !IsInWater)
1503 inwater = false;
1504
1505 // highest available point
1506 tstZ1 = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true, 25.0f);
1507 // upper or floor
1508 tstZ2 = map->GetHeight(phasemask, tstX, tstY, prevZ, true, 25.0f);
1509 //lower than floor
1510 tstZ3 = map->GetHeight(phasemask, tstX, tstY, prevZ - maxtravelDistZ / 2, true, 25.0f);
1511
1512 //distance of rays, will select the shortest in 3D
1513 srange1 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ1 - prevZ) * (tstZ1 - prevZ));
1514 //LOG_ERROR("spells", "step = {}, distance of ray1 = {}", j, srange1);
1515 srange2 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ2 - prevZ) * (tstZ2 - prevZ));
1516 //LOG_ERROR("spells", "step = {}, distance of ray2 = {}", j, srange2);
1517 srange3 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ3 - prevZ) * (tstZ3 - prevZ));
1518 //LOG_ERROR("spells", "step = {}, distance of ray3 = {}", j, srange3);
1519
1520 if (srange1 < srange2)
1521 {
1522 tstZ = tstZ1;
1523 srange = srange1;
1524 }
1525 else if (srange3 < srange2)
1526 {
1527 tstZ = tstZ3;
1528 srange = srange3;
1529 }
1530 else
1531 {
1532 tstZ = tstZ2;
1533 srange = srange2;
1534 }
1535
1536 //LOG_ERROR("spells", "step on ground, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1537 }
1538
1539 destx = tstX;
1540 desty = tstY;
1541 destz = tstZ;
1542
1543 totalpath += srange;
1544
1545 if (totalpath > distance)
1546 {
1547 overdistance = totalpath - distance;
1548 //LOG_ERROR("spells", "total path > than distance in 3D , need to move back a bit for save distance, total path = {}, overdistance = {}", totalpath, overdistance);
1549 }
1550
1551 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1552 // check dynamic collision
1553 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1554
1555 // collision occured
1556 if (col || dcol || (overdistance > 0.0f && !map->IsInWater(phasemask, tstX, tstY, ground, collisionHeight)) || (fabs(prevZ - tstZ) > maxtravelDistZ && (tstZ > prevZ)))
1557 {
1558 if ((overdistance > 0.0f) && (overdistance < 1.f))
1559 {
1560 destx = prevX + overdistance * cos(pos.GetOrientation());
1561 desty = prevY + overdistance * sin(pos.GetOrientation());
1562 //LOG_ERROR("spells", "(collision) collision occured 1");
1563 }
1564 else
1565 {
1566 // move back a bit
1567 destx = tstX - (0.6 * cos(pos.GetOrientation()));
1568 desty = tstY - (0.6 * sin(pos.GetOrientation()));
1569 //LOG_ERROR("spells", "(collision) collision occured 2");
1570 }
1571
1572 // highest available point
1573 destz1 = map->GetHeight(phasemask, destx, desty, prevZ + maxtravelDistZ, true, 25.0f);
1574 // upper or floor
1575 destz2 = map->GetHeight(phasemask, destx, desty, prevZ, true, 25.0f);
1576 //lower than floor
1577 destz3 = map->GetHeight(phasemask, destx, desty, prevZ - maxtravelDistZ / 2, true, 25.0f);
1578
1579 //distance of rays, will select the shortest in 3D
1580 srange1 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz1 - prevZ) * (destz1 - prevZ));
1581 srange2 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz2 - prevZ) * (destz2 - prevZ));
1582 srange3 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz3 - prevZ) * (destz3 - prevZ));
1583
1584 if (srange1 < srange2)
1585 destz = destz1;
1586 else if (srange3 < srange2)
1587 destz = destz3;
1588 else
1589 destz = destz2;
1590
1591 if (inwater && destz < prevZ && !wcol)
1592 destz = prevZ;
1593 //LOG_ERROR("spells", "(collision) destZ rewrited in prevZ");
1594
1595 // Don't make the player move backward from the xy adjustments by collisions.
1596 if ((DELTA_X > 0 && startx > destx) || (DELTA_X < 0 && startx < destx) ||
1597 (DELTA_Y > 0 && starty > desty) || (DELTA_Y < 0 && starty < desty))
1598 {
1599 destx = startx;
1600 desty = starty;
1601 destz = startz;
1602 }
1603
1604 break;
1605 }
1606 // we have correct destz now
1607 }
1608
1609 lastpos.Relocate(destx, desty, destz, pos.GetOrientation());
1610 dest = SpellDestination(lastpos);
1611 }
1612 else
1613 {
1614 float z = pos.GetPositionZ();
1615 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1616 // check dynamic collision
1617 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1618
1619 // collision occured
1620 if (col || dcol)
1621 {
1622 // move back a bit
1623 destx = destx - (0.6 * cos(pos.GetOrientation()));
1624 desty = desty - (0.6 * sin(pos.GetOrientation()));
1625 }
1626
1627 lastpos.Relocate(destx, desty, z, pos.GetOrientation());
1628 dest = SpellDestination(lastpos);
1629 //float range = sqrt((desty - pos.GetPositionY())*(desty - pos.GetPositionY()) + (destx - pos.GetPositionX())*(destx - pos.GetPositionX()));
1630 //LOG_ERROR("spells", "Blink number 2, in falling but at a hight, distance of blink = {}", range);
1631 }
1632 break;
1633 }
1634 default:
1635 {
1636 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1637 float angle = targetType.CalcDirectionAngle();
1638 float objSize = m_caster->GetCombatReach();
1639
1640 switch (targetType.GetTarget())
1641 {
1643 dist = PET_FOLLOW_DIST;
1644 break;
1646 if (dist > objSize)
1647 dist = objSize + (dist - objSize) * float(rand_norm());
1648 break;
1653 {
1654 static float const DefaultTotemDistance = 3.0f;
1655 if (!m_spellInfo->Effects[effIndex].HasRadius())
1656 dist = DefaultTotemDistance;
1657 break;
1658 }
1659 default:
1660 break;
1661 }
1662
1663 if (dist < objSize)
1664 {
1665 dist = objSize;
1666 }
1667
1668 Position pos = dest._position;
1669 m_caster->MovePositionToFirstCollision(pos, dist, angle);
1670
1671 dest.Relocate(pos);
1672 break;
1673 }
1674 }
1675
1676 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1677 m_targets.SetDst(dest);
1678}
#define VMAP_INVALID_HEIGHT_VALUE
Definition: IVMapMgr.h:49
@ MOVEMENTFLAG_FALLING
Definition: UnitDefines.h:356
#define MAP_ALL_LIQUIDS
Definition: Map.h:160
@ SPELL_EFFECT_BIND
Definition: SharedDefines.h:789
@ SPELL_EFFECT_TELEPORT_UNITS
Definition: SharedDefines.h:783
@ TARGET_DEST_CASTER_RANDOM
Definition: SharedDefines.h:1476
@ TARGET_DEST_DB
Definition: SharedDefines.h:1422
@ TARGET_DEST_CASTER_FRONT_LEAP
Definition: SharedDefines.h:1459
@ TARGET_DEST_CASTER_FRONT_LEFT
Definition: SharedDefines.h:1448
@ TARGET_DEST_CASTER_BACK_RIGHT
Definition: SharedDefines.h:1446
@ TARGET_DEST_CASTER_FISHING
Definition: SharedDefines.h:1443
@ TARGET_DEST_CASTER_BACK_LEFT
Definition: SharedDefines.h:1447
@ TARGET_DEST_CASTER_SUMMON
Definition: SharedDefines.h:1436
@ TARGET_DEST_CASTER
Definition: SharedDefines.h:1423
@ TARGET_DEST_CASTER_FRONT_RIGHT
Definition: SharedDefines.h:1445
@ TARGET_DEST_CASTER_36
Definition: SharedDefines.h:1440
@ TARGET_DEST_HOME
Definition: SharedDefines.h:1418
@ SPELL_FAILED_TOO_SHALLOW
Definition: SharedDefines.h:1105
static VMapMgr2 * createOrGetVMapMgr()
Definition: VMapFactory.cpp:27
bool GetObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist) override
Definition: VMapMgr2.cpp:201
float GetMapHeight(float x, float y, float z, bool vmap=true, float distanceToSearch=50.0f) const
Definition: Object.cpp:3115
void GetNearPoint(WorldObject const *searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle, float controlZ=0, Position const *startPos=nullptr) const
Definition: Object.cpp:2623
float GetCollisionHeight() const override
Return collision height sent to client.
Definition: Unit.cpp:20986
Definition: Map.h:171
float Level
Definition: Map.h:176
LiquidStatus Status
Definition: Map.h:178
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition: Map.cpp:2040
LiquidData const GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, uint8 ReqLiquidType)
Definition: Map.cpp:2201
bool IsInWater(uint32 phaseMask, float x, float y, float z, float collisionHeight) const
Definition: Map.cpp:2500
bool GetObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist)
Definition: Map.cpp:2478
void CallScriptDestinationTargetSelectHandlers(SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8683
Definition: SpellMgr.h:396

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), VMAP::VMapFactory::createOrGetVMapMgr(), DEFAULT_WORLD_OBJECT_SIZE, SpellInfo::Effects, finish(), Unit::GetCollisionHeight(), Unit::GetCombatReach(), Map::GetHeight(), Map::GetLiquidData(), WorldObject::GetMap(), WorldObject::GetMapHeight(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellInfo::GetMinRange(), WorldObject::GetNearPoint(), Map::GetObjectHitPos(), VMAP::VMapMgr2::GetObjectHitPos(), SpellCastTargets::GetObjectTarget(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::HasEffect(), Unit::HasUnitMovementFlag(), SpellInfo::Id, Unit::IsInWater(), Map::IsInWater(), WorldObject::IsWithinLOS(), LiquidData::Level, LOG_DEBUG, m_caster, m_spellInfo, m_targets, MAP_ALL_LIQUIDS, MOVEMENTFLAG_FALLING, WorldObject::MovePositionToFirstCollision(), PET_FOLLOW_DIST, rand_norm(), Position::Relocate(), SpellDestination::Relocate(), SendCastResult(), SendChannelUpdate(), SpellCastTargets::SetDst(), SPELL_EFFECT_BIND, SPELL_EFFECT_TELEPORT_UNITS, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_NOT_HERE, SPELL_FAILED_TOO_SHALLOW, sSpellMgr, LiquidData::Status, TARGET_DEST_CASTER, TARGET_DEST_CASTER_36, TARGET_DEST_CASTER_BACK_LEFT, TARGET_DEST_CASTER_BACK_RIGHT, TARGET_DEST_CASTER_FISHING, TARGET_DEST_CASTER_FRONT_LEAP, TARGET_DEST_CASTER_FRONT_LEFT, TARGET_DEST_CASTER_FRONT_RIGHT, TARGET_DEST_CASTER_RANDOM, TARGET_DEST_CASTER_SUMMON, TARGET_DEST_DB, TARGET_DEST_HOME, Object::ToPlayer(), and VMAP_INVALID_HEIGHT_VALUE.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterObjectTargets()

void Spell::SelectImplicitCasterObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1757{
1758 WorldObject* target = nullptr;
1759 bool checkIfValid = true;
1760
1761 switch (targetType.GetTarget())
1762 {
1763 case TARGET_UNIT_CASTER:
1764 target = m_caster;
1765 checkIfValid = false;
1766 break;
1767 case TARGET_UNIT_MASTER:
1768 target = m_caster->GetCharmerOrOwner();
1769 break;
1770 case TARGET_UNIT_PET:
1771 target = m_caster->GetGuardianPet();
1772 if (!target)
1773 target = m_caster->GetCharm();
1774 break;
1776 if (m_caster->IsSummon())
1777 target = m_caster->ToTempSummon()->GetSummonerUnit();
1778 break;
1780 target = m_caster->GetVehicleBase();
1781 break;
1791 target = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0);
1792 break;
1793 default:
1794 break;
1795 }
1796
1797 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1798
1799 if (target && target->ToUnit())
1800 AddUnitTarget(target->ToUnit(), 1 << effIndex, checkIfValid);
1801}
@ TARGET_UNIT_PASSENGER_1
Definition: SharedDefines.h:1501
@ TARGET_UNIT_PASSENGER_6
Definition: SharedDefines.h:1506
@ TARGET_UNIT_VEHICLE
Definition: SharedDefines.h:1498
@ TARGET_UNIT_PASSENGER_2
Definition: SharedDefines.h:1502
@ TARGET_UNIT_PASSENGER_4
Definition: SharedDefines.h:1504
@ TARGET_UNIT_PASSENGER_7
Definition: SharedDefines.h:1507
@ TARGET_UNIT_MASTER
Definition: SharedDefines.h:1431
@ TARGET_UNIT_PASSENGER_5
Definition: SharedDefines.h:1505
@ TARGET_UNIT_PASSENGER_3
Definition: SharedDefines.h:1503
@ TARGET_UNIT_SUMMONER
Definition: SharedDefines.h:1496
@ TARGET_UNIT_PASSENGER_0
Definition: SharedDefines.h:1500
Unit * GetSummonerUnit() const
Definition: TemporarySummon.cpp:44
Unit * GetVehicleBase() const
Definition: Unit.cpp:18646
Unit * GetPassenger(int8 seatId) const
Definition: Vehicle.cpp:224

References AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), Unit::GetCharm(), Unit::GetCharmerOrOwner(), Unit::GetGuardianPet(), Vehicle::GetPassenger(), TempSummon::GetSummonerUnit(), SpellImplicitTargetInfo::GetTarget(), Object::GetTypeId(), Unit::GetVehicleBase(), Unit::GetVehicleKit(), Unit::IsSummon(), Unit::IsVehicle(), m_caster, TARGET_UNIT_CASTER, TARGET_UNIT_MASTER, TARGET_UNIT_PASSENGER_0, TARGET_UNIT_PASSENGER_1, TARGET_UNIT_PASSENGER_2, TARGET_UNIT_PASSENGER_3, TARGET_UNIT_PASSENGER_4, TARGET_UNIT_PASSENGER_5, TARGET_UNIT_PASSENGER_6, TARGET_UNIT_PASSENGER_7, TARGET_UNIT_PET, TARGET_UNIT_SUMMONER, TARGET_UNIT_VEHICLE, Object::ToCreature(), Unit::ToTempSummon(), Object::ToUnit(), and TYPEID_UNIT.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitChainTargets()

void Spell::SelectImplicitChainTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
WorldObject target,
uint32  effMask 
)
1826{
1827 uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget;
1828 if (Player* modOwner = m_caster->GetSpellModOwner())
1829 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
1830
1831 if (maxTargets > 1)
1832 {
1833 // mark damage multipliers as used
1834 for (uint32 k = effIndex; k < MAX_SPELL_EFFECTS; ++k)
1835 if (effMask & (1 << k))
1836 m_damageMultipliers[k] = 1.0f;
1837 m_applyMultiplierMask |= effMask;
1838
1839 std::list<WorldObject*> targets;
1840 SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType(), targetType.GetSelectionCategory()
1841 , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
1842
1843 // Chain primary target is added earlier
1844 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1845
1846 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1847 if (Unit* unitTarget = (*itr)->ToUnit())
1848 AddUnitTarget(unitTarget, effMask, false);
1849 }
1850}
@ SPELLMOD_JUMP_TARGETS
Definition: SpellDefines.h:94
@ TARGET_UNIT_TARGET_CHAINHEAL_ALLY
Definition: SharedDefines.h:1449
void SearchChainTargets(std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
Definition: Spell.cpp:2195

References AddUnitTarget(), CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, SpellImplicitTargetInfo::GetCheckType(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetSelectionCategory(), Unit::GetSpellModOwner(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::Id, m_applyMultiplierMask, m_caster, m_damageMultipliers, m_spellInfo, MAX_SPELL_EFFECTS, SearchChainTargets(), SPELLMOD_JUMP_TARGETS, TARGET_UNIT_TARGET_CHAINHEAL_ALLY, Object::ToUnit(), and unitTarget.

Referenced by SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ SelectImplicitChannelTargets()

void Spell::SelectImplicitChannelTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1041{
1042 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1043 {
1044 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target reference type");
1045 return;
1046 }
1047
1048 switch (targetType.GetTarget())
1049 {
1051 {
1052 // Xinef: All channel selectors have needed data passed in m_targets structure
1054 if (target)
1055 {
1056 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1057 // unit target may be no longer avalible - teleported out of map for example
1058 if (target && target->ToUnit())
1059 AddUnitTarget(target->ToUnit(), 1 << effIndex);
1060 }
1061 else
1062 {
1063 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1064 }
1065 break;
1066 }
1071 {
1072 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1073 if (target)
1074 m_targets.SetDst(*target);
1075 }
1077 {
1078 if (channeledSpell->m_targets.GetUnitTarget())
1079 m_targets.SetDst(*channeledSpell->m_targets.GetUnitTarget());
1080 }
1081 else //if (!m_targets.HasDst())
1082 {
1083 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell destination for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1084 }
1085 break;
1087 if (GetOriginalCaster())
1089 break;
1090 default:
1091 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target type");
1092 break;
1093 }
1094}
@ TARGET_DEST_CHANNEL_TARGET
Definition: SharedDefines.h:1480
@ TARGET_UNIT_CHANNEL_TARGET
Definition: SharedDefines.h:1481
@ TARGET_DEST_CHANNEL_CASTER
Definition: SharedDefines.h:1510
WorldObject * GetObjectTargetChannel(Unit *caster) const
Definition: Spell.cpp:464
SpellDestination const * GetDstChannel() const
Definition: Spell.cpp:474
bool HasDstChannel() const
Definition: Spell.cpp:469

References AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), CURRENT_CHANNELED_SPELL, Unit::GetCurrentSpell(), SpellCastTargets::GetDstChannel(), SpellCastTargets::GetObjectTargetChannel(), GetOriginalCaster(), SpellImplicitTargetInfo::GetReferenceType(), SpellImplicitTargetInfo::GetTarget(), SpellCastTargets::HasDstChannel(), SpellInfo::Id, LOG_DEBUG, m_caster, m_originalCaster, m_spellInfo, m_targets, SpellCastTargets::SetDst(), TARGET_DEST_CHANNEL_CASTER, TARGET_DEST_CHANNEL_TARGET, TARGET_REFERENCE_TYPE_CASTER, TARGET_UNIT_CHANNEL_TARGET, and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitConeTargets()

void Spell::SelectImplicitConeTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1211{
1212 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1213 {
1214 ASSERT(false && "Spell::SelectImplicitConeTargets: received not implemented target reference type");
1215 return;
1216 }
1217 std::list<WorldObject*> targets;
1218 SpellTargetObjectTypes objectType = targetType.GetObjectType();
1219 SpellTargetCheckTypes selectionType = targetType.GetCheckType();
1220 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1221 float coneAngle = M_PI / 2;
1222 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1223
1224 if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList))
1225 {
1226 Acore::WorldObjectSpellConeTargetCheck check(coneAngle, radius, m_caster, m_spellInfo, selectionType, condList);
1227 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
1228 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> >(searcher, containerTypeMask, m_caster, m_caster, radius);
1229
1230 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1231
1232 if (!targets.empty())
1233 {
1234 // Other special target selection goes here
1235 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1236 {
1238 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
1239 if ((*j)->IsAffectedOnSpell(m_spellInfo))
1240 maxTargets += (*j)->GetAmount();
1241
1242 Acore::Containers::RandomResize(targets, maxTargets);
1243 }
1244
1245 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1246 {
1247 if (Unit* unit = (*itr)->ToUnit())
1248 {
1249 AddUnitTarget(unit, effMask, false);
1250 }
1251 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1252 {
1253 AddGOTarget(gObjTarget, effMask);
1254 }
1255 }
1256 }
1257 }
1258}
SpellTargetCheckTypes
Definition: SpellInfo.h:113
SpellTargetObjectTypes
Definition: SpellInfo.h:97

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, Unit::GetAuraEffectsByType(), SpellImplicitTargetInfo::GetCheckType(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), GetSearcherTypeMask(), m_caster, m_spellInfo, m_spellValue, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, Acore::Containers::RandomResize(), SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, TARGET_REFERENCE_TYPE_CASTER, Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitDestDestTargets()

void Spell::SelectImplicitDestDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1718{
1719 // set destination to caster if no dest provided
1720 // can only happen if previous destination target could not be set for some reason
1721 // (not found nearby target, or channel target for example
1722 // maybe we should abort the spell in such case?
1723 CheckDst();
1724
1726
1727 switch (targetType.GetTarget())
1728 {
1732 case TARGET_DEST_DEST:
1733 return;
1734 case TARGET_DEST_TRAJ:
1735 SelectImplicitTrajTargets(effIndex, targetType);
1736 return;
1737 default:
1738 {
1739 float angle = targetType.CalcDirectionAngle();
1740 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1741 if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
1742 dist *= float(rand_norm());
1743
1744 Position pos = dest._position;
1745 m_caster->MovePosition(pos, dist, angle);
1746
1747 dest.Relocate(pos);
1748 break;
1749 }
1750 }
1751
1752 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1753 m_targets.ModDst(dest);
1754}
@ TARGET_DEST_DYNOBJ_ENEMY
Definition: SharedDefines.h:1432
@ TARGET_DEST_DEST_RANDOM
Definition: SharedDefines.h:1490
@ TARGET_DEST_DEST
Definition: SharedDefines.h:1491
@ TARGET_DEST_DYNOBJ_NONE
Definition: SharedDefines.h:1492
@ TARGET_DEST_DYNOBJ_ALLY
Definition: SharedDefines.h:1433
@ TARGET_DEST_TRAJ
Definition: SharedDefines.h:1493
void MovePosition(Position &pos, float dist, float angle)
Definition: Object.cpp:2773
void ModDst(Position const &pos)
Definition: Spell.cpp:436
SpellDestination const * GetDst() const
Definition: Spell.cpp:396

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), CheckDst(), SpellInfo::Effects, SpellCastTargets::GetDst(), SpellImplicitTargetInfo::GetTarget(), m_caster, m_spellInfo, m_targets, SpellCastTargets::ModDst(), WorldObject::MovePosition(), rand_norm(), SpellDestination::Relocate(), SelectImplicitTrajTargets(), TARGET_DEST_DEST, TARGET_DEST_DEST_RANDOM, TARGET_DEST_DYNOBJ_ALLY, TARGET_DEST_DYNOBJ_ENEMY, TARGET_DEST_DYNOBJ_NONE, and TARGET_DEST_TRAJ.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitNearbyTargets()

void Spell::SelectImplicitNearbyTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1097{
1098 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1099 {
1100 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target reference type");
1101 return;
1102 }
1103
1104 float range = 0.0f;
1105 switch (targetType.GetCheckType())
1106 {
1107 case TARGET_CHECK_ENEMY:
1108 range = m_spellInfo->GetMaxRange(false, m_caster, this);
1109 break;
1110 case TARGET_CHECK_ALLY:
1111 case TARGET_CHECK_PARTY:
1112 case TARGET_CHECK_RAID:
1114 range = m_spellInfo->GetMaxRange(true, m_caster, this);
1115 break;
1116 case TARGET_CHECK_ENTRY:
1119 break;
1120 default:
1121 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented selection check type");
1122 break;
1123 }
1124
1125 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1126
1127 // handle emergency case - try to use other provided targets if no conditions provided
1128 if (targetType.GetCheckType() == TARGET_CHECK_ENTRY && (!condList || condList->empty()))
1129 {
1130 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: no conditions entry for target with TARGET_CHECK_ENTRY of spell ID {}, effect {} - selecting default targets", m_spellInfo->Id, effIndex);
1131 switch (targetType.GetObjectType())
1132 {
1135 {
1136 if (focusObject)
1137 AddGOTarget(focusObject, effMask);
1138 return;
1139 }
1140 break;
1143 {
1144 if (focusObject)
1146 return;
1147 }
1148 break;
1149 default:
1150 break;
1151 }
1152 }
1153
1154 WorldObject* target = SearchNearbyTarget(range, targetType.GetObjectType(), targetType.GetCheckType(), condList);
1155 if (!target)
1156 {
1157 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: cannot find nearby target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1158 return;
1159 }
1160
1161 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1162 if (!target)
1163 {
1164 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set nullptr target, effect {}", m_spellInfo->Id, effIndex);
1165 return;
1166 }
1167
1168 switch (targetType.GetObjectType())
1169 {
1171 {
1172 if (Unit* unit = target->ToUnit())
1173 {
1174 AddUnitTarget(unit, effMask, true, false);
1175 // xinef: important! if channeling spell have nearby entry, it has no unitTarget by default
1176 // and if channeled spell has target 77, it requires unitTarget, set it here!
1177 // xinef: if we have NO unit target
1178 if (!m_targets.GetUnitTarget())
1179 {
1181 }
1182 }
1183 else
1184 {
1185 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set object of wrong type, expected unit, got {}, effect {}", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
1186 return;
1187 }
1188 break;
1189 }
1191 if (GameObject* gobjTarget = target->ToGameObject())
1192 AddGOTarget(gobjTarget, effMask);
1193 else
1194 {
1195 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set object of wrong type, expected gameobject, got {}, effect {}", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
1196 return;
1197 }
1198 break;
1200 m_targets.SetDst(*target);
1201 break;
1202 default:
1203 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target object type");
1204 break;
1205 }
1206
1207 SelectImplicitChainTargets(effIndex, targetType, target, effMask);
1208}
@ TARGET_CHECK_PARTY
Definition: SpellInfo.h:118
@ TARGET_CHECK_ENEMY
Definition: SpellInfo.h:116
@ TARGET_CHECK_DEFAULT
Definition: SpellInfo.h:114
@ TARGET_CHECK_RAID_CLASS
Definition: SpellInfo.h:120
@ TARGET_CHECK_ALLY
Definition: SpellInfo.h:117
@ TARGET_CHECK_RAID
Definition: SpellInfo.h:119
WorldObject * SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList=nullptr)
Definition: Spell.cpp:2173
void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
Definition: Spell.cpp:1825

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), SpellInfo::Effects, focusObject, SpellImplicitTargetInfo::GetCheckType(), SpellInfo::GetMaxRange(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetUnitTarget(), SpellInfo::Id, SpellInfo::IsPositive(), LOG_DEBUG, m_caster, m_spellInfo, m_targets, SpellInfo::RequiresSpellFocus, SearchNearbyTarget(), SelectImplicitChainTargets(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), TARGET_CHECK_ALLY, TARGET_CHECK_DEFAULT, TARGET_CHECK_ENEMY, TARGET_CHECK_ENTRY, TARGET_CHECK_PARTY, TARGET_CHECK_RAID, TARGET_CHECK_RAID_CLASS, TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetDestTargets()

void Spell::SelectImplicitTargetDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1681{
1683
1684 SpellDestination dest(*target);
1685
1686 switch (targetType.GetTarget())
1687 {
1690 break;
1691 default:
1692 {
1693 float angle = targetType.CalcDirectionAngle();
1694 float dist = m_spellInfo->Effects[effIndex].CalcRadius(nullptr);
1695 if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
1696 {
1697 dist *= float(rand_norm());
1698 }
1699
1700 if (targetType.GetTarget() == TARGET_DEST_TARGET_BACK)
1701 {
1703 }
1704
1705 Position pos = dest._position;
1706 target->MovePositionToFirstCollision(pos, dist, angle);
1707
1708 dest.Relocate(pos);
1709 break;
1710 }
1711 }
1712
1713 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1714 m_targets.SetDst(dest);
1715}
@ UNIT_FIELD_BOUNDINGRADIUS
Definition: UpdateFields.h:122
@ TARGET_DEST_TARGET_ANY
Definition: SharedDefines.h:1467
@ TARGET_DEST_TARGET_BACK
Definition: SharedDefines.h:1469
@ TARGET_DEST_TARGET_RANDOM
Definition: SharedDefines.h:1478
@ TARGET_DEST_TARGET_ENEMY
Definition: SharedDefines.h:1457

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), SpellInfo::Effects, Object::GetFloatValue(), SpellCastTargets::GetObjectTarget(), SpellImplicitTargetInfo::GetTarget(), m_spellInfo, m_targets, WorldObject::MovePositionToFirstCollision(), rand_norm(), SpellDestination::Relocate(), SpellCastTargets::SetDst(), TARGET_DEST_TARGET_ANY, TARGET_DEST_TARGET_BACK, TARGET_DEST_TARGET_ENEMY, TARGET_DEST_TARGET_RANDOM, and UNIT_FIELD_BOUNDINGRADIUS.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetObjectTargets()

void Spell::SelectImplicitTargetObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1804{
1805 ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!");
1806
1808
1809 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1810
1811 if (target)
1812 {
1813 if (Unit* unit = target->ToUnit())
1814 AddUnitTarget(unit, 1 << effIndex, true, false);
1815 else if (GameObject* gobj = target->ToGameObject())
1816 AddGOTarget(gobj, 1 << effIndex);
1817
1818 SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex);
1819 }
1820 // Script hook can remove object target and we would wrongly land here
1821 else if (Item* item = m_targets.GetItemTarget())
1822 AddItemTarget(item, 1 << effIndex);
1823}

References AddGOTarget(), AddItemTarget(), AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), m_targets, SelectImplicitChainTargets(), Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTrajTargets()

void Spell::SelectImplicitTrajTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
Todo:
: all calculation should be based on src instead of m_caster
1867{
1868 if (!m_targets.HasTraj())
1869 return;
1870
1871 float dist2d = m_targets.GetDist2d();
1872 if (!dist2d)
1873 return;
1874
1875 float srcToDestDelta = m_targets.GetDstPos()->m_positionZ - m_targets.GetSrcPos()->m_positionZ;
1876
1877 // xinef: supply correct target type, DEST_DEST and similar are ALWAYS undefined
1878 // xinef: correct target is stored in TRIGGERED SPELL, however as far as i noticed, all checks are ENTRY, ENEMY
1879 std::list<WorldObject*> targets;
1880 Acore::WorldObjectSpellTrajTargetCheck check(dist2d, m_targets.GetSrcPos(), m_caster, m_spellInfo, TARGET_CHECK_ENEMY /*targetCheckType*/, m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1882 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, m_targets.GetSrcPos(), dist2d);
1883 if (targets.empty())
1884 return;
1885
1887
1888 float b = tangent(m_targets.GetElevation());
1889 float a = (srcToDestDelta - dist2d * b) / (dist2d * dist2d);
1890 if (a > -0.0001f)
1891 a = 0;
1892
1893 LOG_DEBUG("spells", "Spell::SelectTrajTargets: a {} b {}", a, b);
1894
1895 // Xinef: hack for distance, many trajectory spells have RangeEntry 1 (self)
1896 float bestDist = m_spellInfo->GetMaxRange(false) * 2;
1897 if (bestDist < 1.0f)
1898 bestDist = 300.0f;
1899
1900 std::list<WorldObject*>::const_iterator itr = targets.begin();
1901 for (; itr != targets.end(); ++itr)
1902 {
1903 if (Unit* unitTarget = (*itr)->ToUnit())
1904 if (m_caster == *itr || m_caster->IsOnVehicle(unitTarget) || (unitTarget)->GetVehicle())//(*itr)->IsOnVehicle(m_caster))
1905 continue;
1906
1907 const float size = std::max((*itr)->GetObjectSize() * 0.7f, 1.0f); // 1/sqrt(3)
1909 const float objDist2d = std::fabs(m_targets.GetSrcPos()->GetExactDist2d(*itr) * cos(m_targets.GetSrcPos()->GetRelativeAngle(*itr)));
1910 const float dz = std::fabs((*itr)->GetPositionZ() - m_targets.GetSrcPos()->m_positionZ);
1911
1912 LOG_DEBUG("spells", "Spell::SelectTrajTargets: check {}, dist between {} {}, height between {} {}.",
1913 (*itr)->GetEntry(), objDist2d - size, objDist2d + size, dz - size, dz + size);
1914
1915 float dist = objDist2d - size;
1916 float height = dist * (a * dist + b);
1917
1918 LOG_DEBUG("spells", "Spell::SelectTrajTargets: dist {}, height {}.", dist, height);
1919
1920 if (dist < bestDist && height < dz + size && height > dz - size)
1921 {
1922 bestDist = dist > 0 ? dist : 0;
1923 break;
1924 }
1925
1926#define CHECK_DIST {\
1927 LOG_DEBUG("spells", "Spell::SelectTrajTargets: dist {}, height {}.", dist, height);\
1928 if (dist > bestDist)\
1929 continue;\
1930 if (dist < objDist2d + size && dist > objDist2d - size)\
1931 {\
1932 bestDist = dist;\
1933 break;\
1934 }\
1935 }
1936
1937 // RP-GG only, search in straight line, as item have no trajectory
1938 if (m_CastItem)
1939 {
1940 if (dist < bestDist && std::fabs(dz) < 6.0f) // closes target, also check Z difference)
1941 {
1942 bestDist = dist;
1943 break;
1944 }
1945
1946 continue;
1947 }
1948
1949 if (!a)
1950 {
1951 // Xinef: everything remade
1952 dist = m_targets.GetSrcPos()->GetExactDist(*itr);
1953 height = m_targets.GetSrcPos()->GetExactDist2d(*itr) * b;
1954
1955 if (height < dz + size * (b + 1) && height > dz - size * (b + 1) && dist < bestDist)
1956 {
1957 bestDist = dist;
1958 break;
1959 }
1960
1961 continue;
1962 }
1963
1964 height = dz - size;
1965 float sqrt1 = b * b + 4 * a * height;
1966 if (sqrt1 > 0)
1967 {
1968 sqrt1 = std::sqrt(sqrt1);
1969 dist = (sqrt1 - b) / (2 * a);
1970 CHECK_DIST;
1971 }
1972
1973 height = dz + size;
1974 float sqrt2 = b * b + 4 * a * height;
1975 if (sqrt2 > 0)
1976 {
1977 sqrt2 = std::sqrt(sqrt2);
1978 dist = (sqrt2 - b) / (2 * a);
1979 CHECK_DIST;
1980
1981 dist = (-sqrt2 - b) / (2 * a);
1982 CHECK_DIST;
1983 }
1984
1985 if (sqrt1 > 0)
1986 {
1987 dist = (-sqrt1 - b) / (2 * a);
1988 CHECK_DIST;
1989 }
1990 }
1991
1993 {
1994 float x = m_targets.GetSrcPos()->m_positionX + cos(m_caster->GetOrientation()) * bestDist;
1995 float y = m_targets.GetSrcPos()->m_positionY + std::sin(m_caster->GetOrientation()) * bestDist;
1996 float z = m_targets.GetSrcPos()->m_positionZ + bestDist * (a * bestDist + b);
1997
1998 if (itr != targets.end())
1999 {
2000 float distSq = (*itr)->GetExactDistSq(x, y, z);
2001 float sizeSq = (*itr)->GetObjectSize();
2002 sizeSq *= sizeSq;
2003 LOG_DEBUG("spells", "Spell::SelectTrajTargets: Initial {} {} {} {} {}", x, y, z, distSq, sizeSq);
2004 if (distSq > sizeSq)
2005 {
2006 float factor = 1 - std::sqrt(sizeSq / distSq);
2007 x += factor * ((*itr)->GetPositionX() - x);
2008 y += factor * ((*itr)->GetPositionY() - y);
2009 z += factor * ((*itr)->GetPositionZ() - z);
2010
2011 distSq = (*itr)->GetExactDistSq(x, y, z);
2012 LOG_DEBUG("spells", "Spell::SelectTrajTargets: Initial {} {} {} {} {}", x, y, z, distSq, sizeSq);
2013 }
2014 }
2015
2016 Position trajDst;
2017 trajDst.Relocate(x, y, z, m_caster->GetOrientation());
2019 dest.Relocate(trajDst);
2020
2021 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
2022 m_targets.ModDst(dest);
2023 }
2024}
float tangent(float x)
Definition: Spell.cpp:1852
#define CHECK_DIST
Definition: Object.h:687
bool IsOnVehicle(Unit const *vehicle) const
Definition: Unit.h:1697
float GetElevation() const
Definition: Spell.h:168

References CallScriptDestinationTargetSelectHandlers(), CHECK_DIST, SpellInfo::Effects, SpellCastTargets::GetDist2d(), SpellCastTargets::GetDst(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetElevation(), Position::GetExactDist(), Position::GetExactDist2d(), SpellInfo::GetMaxRange(), Position::GetOrientation(), Position::GetRelativeAngle(), SpellCastTargets::GetSrcPos(), GRID_MAP_TYPE_MASK_ALL, SpellCastTargets::HasTraj(), Unit::IsOnVehicle(), LOG_DEBUG, m_caster, m_CastItem, Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_spellInfo, m_targets, SpellCastTargets::ModDst(), Position::Relocate(), SpellDestination::Relocate(), tangent(), TARGET_CHECK_ENEMY, Object::ToUnit(), and unitTarget.

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ SelectSpellTargets()

void Spell::SelectSpellTargets ( )
816{
817 // select targets for cast phase
819
820 uint32 processedAreaEffectsMask = 0;
821 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
822 {
823 // not call for empty effect.
824 // Also some spells use not used effect targets for store targets for dummy effect in triggered spells
825 if (!m_spellInfo->Effects[i].IsEffect())
826 continue;
827
828 // set expected type of implicit targets to be sent to client
829 uint32 implicitTargetMask = GetTargetFlagMask(m_spellInfo->Effects[i].TargetA.GetObjectType()) | GetTargetFlagMask(m_spellInfo->Effects[i].TargetB.GetObjectType());
830 if (implicitTargetMask & TARGET_FLAG_UNIT)
832 if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM))
834
835 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetA, processedAreaEffectsMask);
836 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetB, processedAreaEffectsMask);
837
838 // Select targets of effect based on effect type
839 // those are used when no valid target could be added for spell effect based on spell target type
840 // some spell effects use explicit target as a default target added to target map (like SPELL_EFFECT_LEARN_SPELL)
841 // some spell effects add target to target map only when target type specified (like SPELL_EFFECT_WEAPON)
842 // some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS)
844
845 if (m_targets.HasDst())
847
849 {
850 // maybe do this for all spells?
851 if (!focusObject && m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty() && m_UniqueItemInfo.empty() && !m_targets.HasDst())
852 {
854 finish(false);
855 return;
856 }
857
858 uint8 mask = (1 << i);
859 for (auto ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
860 {
861 if (ihit->effectMask & mask)
862 {
864 break;
865 }
866 }
867 }
868 else if (m_auraScaleMask)
869 {
870 bool checkLvl = !m_UniqueTargetInfo.empty();
871 m_UniqueTargetInfo.erase(std::remove_if(std::begin(m_UniqueTargetInfo), std::end(m_UniqueTargetInfo), [&](TargetInfo const& targetInfo) -> bool
872 {
873 // remove targets which did not pass min level check
874 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask)
875 {
876 if (!targetInfo.scaleAura && targetInfo.targetGUID != m_caster->GetGUID())
877 return true;
878 }
879
880 return false;
881 }), std::end(m_UniqueTargetInfo));
882
883 if (checkLvl && m_UniqueTargetInfo.empty())
884 {
886 finish(false);
887 }
888 }
889 }
890
891 if (uint64 dstDelay = CalculateDelayMomentForDst())
892 m_delayMoment = dstDelay;
893}
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
Definition: SpellInfo.cpp:30
@ TARGET_FLAG_GAMEOBJECT
Definition: SpellInfo.h:57
@ TARGET_FLAG_GAMEOBJECT_ITEM
Definition: SpellInfo.h:60
void SetTargetFlag(SpellCastTargetFlags flag)
Definition: Spell.h:120
void SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 &processedEffectMask)
Definition: Spell.cpp:922
void SelectExplicitTargets()
Definition: Spell.cpp:782
void AddDestTarget(SpellDestination const &dest, uint32 effIndex)
Definition: Spell.cpp:2604
void SelectEffectTypeImplicitTargets(uint8 effIndex)
Definition: Spell.cpp:2026

References AddDestTarget(), CalculateDelayMomentForDst(), TargetInfo::effectMask, SpellInfo::Effects, finish(), focusObject, SpellCastTargets::GetDst(), GetTargetFlagMask(), SpellCastTargets::HasDst(), SpellInfo::IsChanneled(), m_auraScaleMask, m_channelTargetEffectMask, m_delayMoment, m_spellInfo, m_targets, m_UniqueGOTargetInfo, m_UniqueItemInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SendCastResult(), SpellCastTargets::SetTargetFlag(), SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_LOWLEVEL, TARGET_FLAG_GAMEOBJECT, TARGET_FLAG_GAMEOBJECT_ITEM, and TARGET_FLAG_UNIT.

Referenced by _cast(), CanAutoCast(), spell_dk_raise_dead::CheckCast(), and prepare().

◆ SendCastResult() [1/2]

void Spell::SendCastResult ( Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError = SPELL_CUSTOM_ERROR_NONE 
)
static
4656{
4657 if (result == SPELL_CAST_OK)
4658 return;
4659
4660 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
4661 WriteCastResultInfo(data, caster, spellInfo, castCount, result, customError);
4662
4663 caster->GetSession()->SendPacket(&data);
4664}
@ SMSG_CAST_FAILED
Definition: Opcodes.h:334
static void WriteCastResultInfo(WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
Definition: Spell.cpp:4550

References Player::GetSession(), WorldSession::SendPacket(), SMSG_CAST_FAILED, SPELL_CAST_OK, and WriteCastResultInfo().

Referenced by _cast(), Unit::AttackerStateUpdate(), cancel(), Player::CastItemUseSpell(), spell_q12237_rescue_villager::CheckCast(), spell_q12237_drop_off_villager::CheckCast(), spell_dk_raise_dead::CheckReagents(), spell_putricide_mutation_init::CheckRequirement(), EffectApplyGlyph(), EffectDuel(), EffectOpenLock(), EffectTaunt(), SpellScript::FinishCast(), go_soulwell::go_soulwellAI::GossipHello(), WorldSession::HandleAcceptTradeOpcode(), spell_the_flag_of_ownership::HandleFinish(), WorldSession::HandlePetActionHelper(), spell_putricide_mutated_transformation::HandleSummon(), misc_commandscript::HandleUnstuckCommand(), icecrown_citadel_teleport::OnGossipSelect(), at_frozen_throne_teleport::OnTrigger(), item_petrov_cluster_bombs::OnUse(), item_only_for_flight::OnUse(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and SendCastResult().

◆ SendCastResult() [2/2]

void Spell::SendCastResult ( SpellCastResult  result)
4667{
4668 if (result == SPELL_CAST_OK)
4669 return;
4670
4672 return;
4673
4674 if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
4675 return;
4676
4677 // Xinef: override every possible result, except for gm fail result... breaks many things and goes unnoticed because of this and makes me rage when i find this out
4679 result = SPELL_FAILED_DONT_REPORT;
4680
4682}
@ TRIGGERED_DONT_REPORT_CAST_ERROR
Disallows proc events from triggered spell (default)
Definition: SpellDefines.h:147
@ SPELL_FAILED_BM_OR_INVISGOD
Definition: SharedDefines.h:1108
bool IsCharmed() const
Definition: Unit.h:1213

References Player::GetSession(), Object::GetTypeId(), HasTriggeredCastFlag(), Unit::IsCharmed(), m_cast_count, m_caster, m_customError, m_spellInfo, WorldSession::PlayerLoading(), SendCastResult(), SPELL_CAST_OK, SPELL_FAILED_BM_OR_INVISGOD, SPELL_FAILED_DONT_REPORT, Object::ToPlayer(), TRIGGERED_DONT_REPORT_CAST_ERROR, and TYPEID_PLAYER.

◆ SendChannelStart()

void Spell::SendChannelStart ( uint32  duration)
5193{
5194 ObjectGuid channelTarget = m_targets.GetObjectTargetGUID();
5195 if (!channelTarget && !m_spellInfo->NeedsExplicitUnitTarget())
5196 if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1) // this is for TARGET_SELECT_CATEGORY_NEARBY
5197 channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().targetGUID : m_UniqueGOTargetInfo.front().targetGUID;
5198
5199 WorldPacket data(MSG_CHANNEL_START, (8 + 4 + 4));
5200 data << m_caster->GetPackGUID();
5201 data << uint32(m_spellInfo->Id);
5202 data << uint32(duration);
5203
5204 m_caster->SendMessageToSet(&data, true);
5205
5208
5209 m_timer = duration;
5210 if (channelTarget)
5212
5214}
@ MSG_CHANNEL_START
Definition: Opcodes.h:343

References WorldObject::FindMap(), Object::GetGUID(), SpellCastTargets::GetObjectTargetGUID(), Object::GetPackGUID(), Object::GetTypeId(), SpellInfo::Id, m_caster, m_spellInfo, m_targets, m_timer, m_UniqueGOTargetInfo, m_UniqueTargetInfo, MSG_CHANNEL_START, Player::NeedSendSpectatorData(), SpellInfo::NeedsExplicitUnitTarget(), ArenaSpectator::SendCommand_Spell(), WorldObject::SendMessageToSet(), Object::SetGuidValue(), Unit::SetUInt32Value(), Object::ToPlayer(), TYPEID_PLAYER, UNIT_CHANNEL_SPELL, and UNIT_FIELD_CHANNEL_OBJECT.

Referenced by handle_immediate().

◆ SendChannelUpdate()

◆ SendInterrupted()

void Spell::SendInterrupted ( uint8  result)
5161{
5162 WorldPacket data(SMSG_SPELL_FAILURE, (8 + 1 + 4 + 1));
5163 data << m_caster->GetPackGUID();
5164 data << uint8(m_cast_count);
5165 data << uint32(m_spellInfo->Id);
5166 data << uint8(result);
5167 m_caster->SendMessageToSet(&data, true);
5168
5169 data.Initialize(SMSG_SPELL_FAILED_OTHER, (8 + 1 + 4 + 1));
5170 data << m_caster->GetPackGUID();
5171 data << uint8(m_cast_count);
5172 data << uint32(m_spellInfo->Id);
5173 data << uint8(result);
5174 m_caster->SendMessageToSet(&data, true);
5175}
@ SMSG_SPELL_FAILURE
Definition: Opcodes.h:337
@ SMSG_SPELL_FAILED_OTHER
Definition: Opcodes.h:708

References Object::GetPackGUID(), SpellInfo::Id, WorldPacket::Initialize(), m_cast_count, m_caster, m_spellInfo, WorldObject::SendMessageToSet(), SMSG_SPELL_FAILED_OTHER, and SMSG_SPELL_FAILURE.

Referenced by _cast(), Unit::AttackerStateUpdate(), and cancel().

◆ SendLogExecute()

void Spell::SendLogExecute ( )
5060{
5061 WorldPacket data(SMSG_SPELLLOGEXECUTE, (8 + 4 + 4 + 4 + 4 + 8));
5062
5063 data << m_caster->GetPackGUID();
5064
5065 data << uint32(m_spellInfo->Id);
5066
5067 uint8 effCount = 0;
5068 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5069 {
5070 if (m_effectExecuteData[i])
5071 ++effCount;
5072 }
5073
5074 if (!effCount)
5075 return;
5076
5077 data << uint32(effCount);
5078 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5079 {
5080 if (!m_effectExecuteData[i])
5081 continue;
5082
5083 data << uint32(m_spellInfo->Effects[i].Effect); // spell effect
5084
5085 data.append(*m_effectExecuteData[i]);
5086
5087 delete m_effectExecuteData[i];
5088 m_effectExecuteData[i] = nullptr;
5089 }
5090 m_caster->SendMessageToSet(&data, true);
5091}
@ SMSG_SPELLLOGEXECUTE
Definition: Opcodes.h:618

References ByteBuffer::append(), SpellInfo::Effects, Object::GetPackGUID(), SpellInfo::Id, m_caster, m_effectExecuteData, m_spellInfo, MAX_SPELL_EFFECTS, WorldObject::SendMessageToSet(), and SMSG_SPELLLOGEXECUTE.

Referenced by FinishTargetProcessing().

◆ SendLoot()

void Spell::SendLoot ( ObjectGuid  guid,
LootType  loottype 
)
protected
1998{
1999 Player* player = m_caster->ToPlayer();
2000 if (!player)
2001 return;
2002
2003 if (gameObjTarget)
2004 {
2005 // Players shouldn't be able to loot gameobjects that are currently despawned
2006 if (!gameObjTarget->isSpawned() && !player->IsGameMaster())
2007 {
2008 LOG_ERROR("spells.effect", "Possible hacking attempt: Player {} [{}] tried to loot a gameobject [{}] which is on respawn time without being in GM mode!",
2009 player->GetName(), player->GetGUID().ToString(), gameObjTarget->GetGUID().ToString());
2010 return;
2011 }
2012 // special case, already has GossipHello inside so return and avoid calling twice
2014 {
2016 return;
2017 }
2018
2019 if (sScriptMgr->OnGossipHello(player, gameObjTarget))
2020 return;
2021
2022 if (gameObjTarget->AI()->GossipHello(player, false))
2023 return;
2024
2025 switch (gameObjTarget->GetGoType())
2026 {
2028 gameObjTarget->UseDoorOrButton(0, false, player);
2029 return;
2031 gameObjTarget->UseDoorOrButton(0, false, player);
2032
2033 // Xinef: properly link possible traps
2034 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->button.linkedTrap)
2035 gameObjTarget->TriggeringLinkedGameObject(trapEntry, player);
2036 return;
2040 return;
2041
2043 // triggering linked GO
2046 return;
2047
2049 // triggering linked GO
2050 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->chest.linkedTrapId)
2052
2053 // Don't return, let loots been taken
2054 default:
2055 break;
2056 }
2057 }
2058
2059 // Send loot
2060 player->SendLoot(guid, loottype);
2061}
@ GAMEOBJECT_TYPE_SPELL_FOCUS
Definition: SharedDefines.h:1568
@ GAMEOBJECT_TYPE_QUESTGIVER
Definition: SharedDefines.h:1562
virtual bool GossipHello(Player *, bool)
Definition: GameObjectAI.h:55
bool isSpawned() const
Definition: GameObject.h:190
void TriggeringLinkedGameObject(uint32 trapEntry, Unit *target)
Definition: GameObject.cpp:1385
uint32 gossipID
Definition: GameObjectData.h:73
uint32 linkedTrap
Definition: GameObjectData.h:60
struct GameObjectTemplate::@227::@232 chest
struct GameObjectTemplate::@227::@236 spellFocus
uint32 linkedTrapId
Definition: GameObjectData.h:91
struct GameObjectTemplate::@227::@231 questgiver
void SendPreparedGossip(WorldObject *source)
Definition: PlayerGossip.cpp:209
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition: PlayerGossip.cpp:32

References GameObject::AI(), GameObjectTemplate::button, GameObjectTemplate::chest, GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_QUESTGIVER, GAMEOBJECT_TYPE_SPELL_FOCUS, gameObjTarget, GameObject::GetGOInfo(), GameObject::GetGoType(), Object::GetGUID(), WorldObject::GetName(), GameObjectAI::GossipHello(), GameObjectTemplate::gossipID, Player::IsGameMaster(), GameObject::isSpawned(), GameObjectTemplate::linkedTrap, GameObjectTemplate::linkedTrapId, LOG_ERROR, m_caster, Player::PrepareGossipMenu(), GameObjectTemplate::questgiver, Player::SendLoot(), Player::SendPreparedGossip(), GameObjectTemplate::spellFocus, sScriptMgr, Object::ToPlayer(), ObjectGuid::ToString(), GameObject::TriggeringLinkedGameObject(), GameObject::Use(), and GameObject::UseDoorOrButton().

Referenced by EffectOpenLock().

◆ SendPetCastResult()

void Spell::SendPetCastResult ( SpellCastResult  result)
4685{
4686 if (result == SPELL_CAST_OK)
4687 return;
4688
4689 Unit* owner = m_caster->GetCharmerOrOwner();
4690 if (!owner)
4691 return;
4692
4693 Player* player = owner->ToPlayer();
4694 if (!player)
4695 return;
4696
4697 WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1);
4699
4700 player->GetSession()->SendPacket(&data);
4701}
@ SMSG_PET_CAST_FAILED
Definition: Opcodes.h:342

References Unit::GetCharmerOrOwner(), Player::GetSession(), m_cast_count, m_caster, m_customError, m_spellInfo, WorldSession::SendPacket(), SMSG_PET_CAST_FAILED, SPELL_CAST_OK, Object::ToPlayer(), and WriteCastResultInfo().

Referenced by WorldSession::HandlePetActionHelper(), and WorldSession::HandlePetCastSpellOpcode().

◆ SendResurrectRequest()

void Spell::SendResurrectRequest ( Player target)
5217{
5218 // get resurrector name for creature resurrections, otherwise packet will be not accepted
5219 // for player resurrections the name is looked up by guid
5220 std::string const sentName(m_caster->GetTypeId() == TYPEID_PLAYER
5221 ? ""
5223
5224 WorldPacket data(SMSG_RESURRECT_REQUEST, (8 + 4 + sentName.size() + 1 + 1 + 1 + 4));
5225 data << m_caster->GetGUID();
5226 data << uint32(sentName.size() + 1);
5227
5228 data << sentName;
5229 data << uint8(0); // null terminator
5230
5231 data << uint8(m_caster->GetTypeId() == TYPEID_PLAYER ? 0 : 1); // "you'll be afflicted with resurrection sickness"
5232 // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
5234 data << uint32(0);
5235 target->GetSession()->SendPacket(&data);
5236}
@ SPELL_ATTR3_NO_RES_TIMER
Definition: SharedDefines.h:497
@ SMSG_RESURRECT_REQUEST
Definition: Opcodes.h:377
virtual std::string const & GetNameForLocaleIdx(LocaleConstant) const
Definition: Object.h:452
LocaleConstant GetSessionDbLocaleIndex() const
Definition: WorldSession.h:498

References Object::GetGUID(), WorldObject::GetNameForLocaleIdx(), Player::GetSession(), WorldSession::GetSessionDbLocaleIndex(), Object::GetTypeId(), SpellInfo::HasAttribute(), m_caster, m_spellInfo, WorldSession::SendPacket(), SMSG_RESURRECT_REQUEST, SPELL_ATTR3_NO_RES_TIMER, and TYPEID_PLAYER.

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ SendSpellCooldown()

void Spell::SendSpellCooldown ( )
4347{
4348 // xinef: properly add creature cooldowns
4350 {
4352 {
4353 // xinef: this should be added here
4354 //m_caster->AddSpellCooldown(m_spellInfo->Id, 0, 0);
4355
4356 // xinef: this adds cooldowns to vehicle spells which misses them client-side (when we overwrote dbc info in eg.)
4359 {
4360 WorldPacket data(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4);
4361 data << m_caster->GetGUID();
4363 data << uint32(m_spellInfo->Id);
4365 player->SendDirectMessage(&data);
4366 }
4367 }
4368 return;
4369 }
4370
4371 Player* _player = m_caster->ToPlayer();
4372
4373 // mana/health/etc potions, disabled by client (until combat out as declarate)
4375 {
4376 // need in some way provided data for Spell::finish SendCooldownEvent
4377 _player->SetLastPotionId(m_CastItem->GetEntry());
4378 return;
4379 }
4380
4381 // have infinity cooldown but set at aura apply
4382 // do not set cooldown for triggered spells (needed by reincarnation)
4387 return;
4388
4390}
@ SPELL_COOLDOWN_FLAG_INCLUDE_GCD
Starts GCD in addition to normal cooldown specified in the packet.
Definition: Unit.h:617
@ SMSG_SPELL_COOLDOWN
Definition: Opcodes.h:338
void SetLastPotionId(uint32 item_id)
Definition: Player.h:1789
void AddSpellAndCategoryCooldowns(SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool infinityCooldown=false)
Definition: Player.cpp:10863
uint32 RecoveryTime
Definition: SpellInfo.h:348
bool RequireCooldownInfo() const
Definition: SpellInfo.cpp:1181

References Player::AddSpellAndCategoryCooldowns(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetEntry(), Object::GetGUID(), Object::GetTypeId(), HasTriggeredCastFlag(), SpellInfo::Id, SpellInfo::IsCooldownStartedOnEvent(), SpellInfo::IsPassive(), Item::IsPotion(), m_caster, m_CastItem, m_spellInfo, SpellInfo::RecoveryTime, SpellInfo::RequireCooldownInfo(), Player::SetLastPotionId(), SMSG_SPELL_COOLDOWN, SPELL_COOLDOWN_FLAG_INCLUDE_GCD, Object::ToPlayer(), TRIGGERED_IGNORE_EFFECTS, TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD, and TYPEID_PLAYER.

Referenced by _cast().

◆ SendSpellGo()

void Spell::SendSpellGo ( )
4784{
4785 // not send invisible spell casting
4786 if (!IsNeedSendToClient(true))
4787 return;
4788
4789 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_GO id={}", m_spellInfo->Id);
4790
4791 uint32 castFlags = CAST_FLAG_UNKNOWN_9;
4792
4793 // triggered spells with spell visual != 0
4795 castFlags |= CAST_FLAG_PENDING;
4796
4798 castFlags |= CAST_FLAG_PROJECTILE; // arrows/bullets visual
4799
4800 // should only be sent to self, but the current messaging doesn't make that possible
4802 {
4803 switch (m_spellInfo->PowerType)
4804 {
4805 case POWER_HEALTH:
4806 break;
4807 case POWER_RUNE:
4808 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4809 break;
4810 default:
4811 if (m_powerCost != 0)
4812 {
4813 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4814 }
4815 break;
4816 }
4817 }
4818
4819 if ((m_caster->GetTypeId() == TYPEID_PLAYER)
4823 {
4824 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4825 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4826 }
4827
4829 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4830
4831 if (m_targets.HasTraj())
4832 castFlags |= CAST_FLAG_ADJUST_MISSILE;
4833
4835 castFlags |= CAST_FLAG_NO_GCD;
4836
4837 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4838 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4839 {
4840 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4841 {
4842 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4843 {
4844 realCasterGUID = casterGameobject->GetPackGUID();
4845 }
4846 }
4847 }
4848
4849 WorldPacket data(SMSG_SPELL_GO, 150); // guess size
4850
4851 if (m_CastItem)
4852 data << m_CastItem->GetPackGUID();
4853 else
4854 data << realCasterGUID;
4855
4856 data << realCasterGUID;
4857 data << uint8(m_cast_count); // pending spell cast?
4858 data << uint32(m_spellInfo->Id); // spellId
4859 data << uint32(castFlags); // cast flags
4860 data << uint32(GameTime::GetGameTimeMS().count()); // timestamp
4861
4862 WriteSpellGoTargets(&data);
4863
4864 m_targets.Write(data);
4865
4866 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4868
4869 if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list
4870 {
4871 //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature
4872 //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
4873 if (Player* player = m_caster->ToPlayer())
4874 {
4875 uint8 runeMaskInitial = m_runesState;
4876 uint8 runeMaskAfterCast = player->GetRunesState();
4877 data << uint8(runeMaskInitial); // runes state before
4878 data << uint8(runeMaskAfterCast); // runes state after
4879 for (uint8 i = 0; i < MAX_RUNES; ++i)
4880 {
4881 uint8 mask = (1 << i);
4882 if (mask & runeMaskInitial && !(mask & runeMaskAfterCast)) // usable before andon cooldown now...
4883 {
4884 // float casts ensure the division is performed on floats as we need float result
4885 float baseCd = float(player->GetRuneBaseCooldown(i, true));
4886 data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
4887 }
4888 }
4889 }
4890 }
4891 if (castFlags & CAST_FLAG_ADJUST_MISSILE)
4892 {
4893 data << m_targets.GetElevation();
4895 }
4896
4897 if (castFlags & CAST_FLAG_PROJECTILE)
4898 WriteAmmoToPacket(&data);
4899
4900 if (castFlags & CAST_FLAG_VISUAL_CHAIN)
4901 {
4902 data << uint32(0);
4903 data << uint32(0);
4904 }
4905
4907 {
4908 data << uint8(0);
4909 }
4910
4911 m_caster->SendMessageToSet(&data, true);
4912}
@ CAST_FLAG_VISUAL_CHAIN
Definition: Spell.h:63
@ CAST_FLAG_ADJUST_MISSILE
Definition: Spell.h:61
@ CAST_FLAG_UNKNOWN_9
Definition: Spell.h:52
@ CAST_FLAG_NO_GCD
Definition: Spell.h:62
@ CAST_FLAG_PROJECTILE
Definition: Spell.h:49
@ CAST_FLAG_POWER_LEFT_SELF
Definition: Spell.h:55
@ CAST_FLAG_RUNE_LIST
Definition: Spell.h:65
@ CAST_FLAG_PENDING
Definition: Spell.h:44
@ SPELL_ATTR0_CU_NEEDS_AMMO_DATA
Definition: SpellInfo.h:195
@ SPELL_EFFECT_ACTIVATE_RUNE
Definition: SharedDefines.h:924
@ SPELL_ATTR0_USES_RANGED_SLOT
Definition: SharedDefines.h:383
@ SMSG_SPELL_GO
Definition: Opcodes.h:336
Definition: ObjectGuid.h:263
void Write(ByteBuffer &data)
Definition: Spell.cpp:179
void WriteSpellGoTargets(WorldPacket *data)
Writes miss and hit targets for a SMSG_SPELL_GO packet.
Definition: Spell.cpp:4999
void WriteAmmoToPacket(WorldPacket *data)
Definition: Spell.cpp:4914
bool IsNeedSendToClient(bool go) const
Definition: Spell.cpp:8077
SpellCastTimesEntry const * CastTimeEntry
Definition: SpellInfo.h:347
int32 CastTime
Definition: DBCStructure.h:1760

References CAST_FLAG_ADJUST_MISSILE, CAST_FLAG_NO_GCD, CAST_FLAG_PENDING, CAST_FLAG_POWER_LEFT_SELF, CAST_FLAG_PROJECTILE, CAST_FLAG_RUNE_LIST, CAST_FLAG_UNKNOWN_9, CAST_FLAG_VISUAL_CHAIN, SpellCastTimesEntry::CastTime, SpellInfo::CastTimeEntry, CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, SpellCastTargets::GetElevation(), GameTime::GetGameTimeMS(), Object::GetPackGUID(), Unit::GetPower(), SpellCastTargets::GetTargetMask(), Object::GetTypeId(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), Unit::IsClass(), IsNeedSendToClient(), Unit::IsPet(), IsTriggered(), m_cast_count, m_caster, m_CastItem, m_delayMoment, m_delayTrajectory, m_powerCost, m_runesState, m_spellInfo, m_targets, m_triggeredByAuraSpell, MAX_RUNES, POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, WorldObject::SendMessageToSet(), SMSG_SPELL_GO, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_EFFECT_ACTIVATE_RUNE, SpellInfo::StartRecoveryTime, TARGET_FLAG_DEST_LOCATION, Object::ToPlayer(), Unit::ToTempSummon(), TYPEID_PLAYER, WORLD_TRIGGER, SpellCastTargets::Write(), WriteAmmoToPacket(), and WriteSpellGoTargets().

Referenced by _cast().

◆ SendSpellStart()

void Spell::SendSpellStart ( )
4704{
4705 if (!IsNeedSendToClient(false))
4706 return;
4707
4708 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_START id={}", m_spellInfo->Id);
4709
4710 uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
4711
4713 castFlags |= CAST_FLAG_PENDING;
4714
4716 castFlags |= CAST_FLAG_PROJECTILE;
4717
4719 {
4720 switch (m_spellInfo->PowerType)
4721 {
4722 case POWER_HEALTH:
4723 break;
4724 case POWER_RUNE:
4725 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4726 break;
4727 default:
4728 if (m_powerCost != 0)
4729 {
4730 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4731 }
4732 break;
4733 }
4734 }
4735
4737 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4738
4739 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4740 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4741 {
4742 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4743 {
4744 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4745 {
4746 realCasterGUID = casterGameobject->GetPackGUID();
4747 }
4748 }
4749 }
4750
4751 WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2));
4752 if (m_CastItem)
4753 data << m_CastItem->GetPackGUID();
4754 else
4755 data << realCasterGUID;
4756
4757 data << realCasterGUID;
4758 data << uint8(m_cast_count); // pending spell cast?
4759 data << uint32(m_spellInfo->Id); // spellId
4760 data << uint32(castFlags); // cast flags
4761 data << int32(m_timer); // delay?
4762
4763 m_targets.Write(data);
4764
4765 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4767
4768 if (castFlags & CAST_FLAG_PROJECTILE)
4769 WriteAmmoToPacket(&data);
4770
4771 if (castFlags & CAST_FLAG_UNKNOWN_23)
4772 {
4773 data << uint32(0);
4774 data << uint32(0);
4775 }
4776
4777 m_caster->SendMessageToSet(&data, true);
4778
4781}
@ CAST_FLAG_UNKNOWN_23
Definition: Spell.h:66
@ CAST_FLAG_HAS_TRAJECTORY
Definition: Spell.h:45
@ SMSG_SPELL_START
Definition: Opcodes.h:335

References CAST_FLAG_HAS_TRAJECTORY, CAST_FLAG_NO_GCD, CAST_FLAG_PENDING, CAST_FLAG_POWER_LEFT_SELF, CAST_FLAG_PROJECTILE, CAST_FLAG_UNKNOWN_23, SpellCastTimesEntry::CastTime, SpellInfo::CastTimeEntry, WorldObject::FindMap(), Object::GetGUID(), Object::GetPackGUID(), Unit::GetPower(), Object::GetTypeId(), SpellInfo::HasAttribute(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), IsNeedSendToClient(), Unit::IsPet(), IsTriggered(), m_cast_count, m_caster, m_CastItem, m_powerCost, m_spellInfo, m_targets, m_timer, m_triggeredByAuraSpell, Player::NeedSendSpectatorData(), POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, ArenaSpectator::SendCommand_Spell(), WorldObject::SendMessageToSet(), SMSG_SPELL_START, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_USES_RANGED_SLOT, Object::ToPlayer(), Unit::ToTempSummon(), TYPEID_PLAYER, WORLD_TRIGGER, SpellCastTargets::Write(), and WriteAmmoToPacket().

Referenced by prepare().

◆ SetAutoRepeat()

void Spell::SetAutoRepeat ( bool  rep)
inline
549{ m_autoRepeat = rep; }

References m_autoRepeat.

◆ SetDelayStart()

void Spell::SetDelayStart ( uint64  m_time)
inline
563{ m_delayStart = m_time; }

References m_delayStart.

Referenced by _cast(), and SpellEvent::Execute().

◆ SetExecutedCurrently()

void Spell::SetExecutedCurrently ( bool  yes)
inline
561{m_executedCurrently = yes;}

References m_executedCurrently.

Referenced by _cast(), and Unit::AttackerStateUpdate().

◆ SetReferencedFromCurrent()

void Spell::SetReferencedFromCurrent ( bool  yes)
inline

◆ SetSpellValue()

void Spell::SetSpellValue ( SpellValueMod  mod,
int32  value 
)
8419{
8420 switch (mod)
8421 {
8423 m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value);
8424 break;
8426 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value);
8427 break;
8429 m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value);
8430 break;
8432 m_spellValue->RadiusMod = (float)value / 10000;
8433 break;
8436 break;
8439 break;
8441 m_spellValue->AuraDuration = value;
8442 break;
8444 m_spellValue->ForcedCritResult = (bool)value;
8445 break;
8446 }
8447}
@ SPELLVALUE_AURA_STACK
Definition: SpellDefines.h:119
@ SPELLVALUE_AURA_DURATION
Definition: SpellDefines.h:120
@ SPELLVALUE_RADIUS_MOD
Definition: SpellDefines.h:117
@ SPELLVALUE_MAX_TARGETS
Definition: SpellDefines.h:118
@ SPELLVALUE_FORCED_CRIT_RESULT
Definition: SpellDefines.h:121
bool ForcedCritResult
Definition: Spell.h:218

References SpellValue::AuraDuration, SpellValue::AuraStackAmount, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, SpellInfo::Effects, SpellValue::ForcedCritResult, m_spellInfo, m_spellValue, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, SPELLVALUE_AURA_DURATION, SPELLVALUE_AURA_STACK, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, SPELLVALUE_FORCED_CRIT_RESULT, SPELLVALUE_MAX_TARGETS, and SPELLVALUE_RADIUS_MOD.

Referenced by Player::CastItemUseSpell(), Unit::CastSpell(), and spell_gen_mod_radius_by_caster_scale::PrepareSpellScript().

◆ setState()

void Spell::setState ( uint32  state)
inline
483{ m_spellState = state; }

References m_spellState.

◆ SummonGuardian()

void Spell::SummonGuardian ( uint32  i,
uint32  entry,
SummonPropertiesEntry const *  properties,
uint32  numSummons,
bool  personalSpawn 
)
protected
5933{
5934 Unit* caster = m_originalCaster;
5935 if (!caster)
5936 return;
5937
5938 if (caster->IsTotem())
5939 caster = caster->ToTotem()->GetOwner();
5940
5941 // in another case summon new
5942 uint8 summonLevel = caster->GetLevel();
5943
5944 // level of pet summoned using engineering item based at engineering skill level
5945 if (m_CastItem && caster->GetTypeId() == TYPEID_PLAYER)
5946 if (ItemTemplate const* proto = m_CastItem->GetTemplate())
5947 {
5948 // xinef: few special cases
5949 if (proto->RequiredSkill == SKILL_ENGINEERING)
5950 {
5951 if (uint16 skill202 = caster->ToPlayer()->GetSkillValue(SKILL_ENGINEERING))
5952 summonLevel = skill202 / 5;
5953 }
5954
5955 switch (m_spellInfo->Id)
5956 {
5957 // Dragon's Call
5958 case 13049:
5959 summonLevel = 55;
5960 break;
5961
5962 // Cleansed Timberling Heart: Summon Timberling
5963 case 5666:
5964 summonLevel = 7;
5965 break;
5966
5967 // Glowing Cat Figurine: Summon Ghost Saber
5968 case 6084:
5969 // minLevel 19, maxLevel 20
5970 summonLevel = 20;
5971 break;
5972
5973 // Spiked Collar: Summon Felhunter
5974 case 8176:
5975 summonLevel = 30;
5976 break;
5977
5978 // Dog Whistle: Summon Tracking Hound
5979 case 9515:
5980 summonLevel = 30;
5981 break;
5982
5983 // Barov Peasant Caller: Death by Peasant
5984 case 18307:
5985 case 18308:
5986 summonLevel = 60;
5987 break;
5988
5989 // Thornling Seed: Plant Thornling
5990 case 22792:
5991 summonLevel = 60;
5992 break;
5993
5994 // Cannonball Runner: Summon Crimson Cannon
5995 case 6251:
5996 summonLevel = 61;
5997 break;
5998 }
5999 }
6000
6001 summonLevel = std::min<uint8>(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) + sWorld->getIntConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF), std::max<uint8>(1U, summonLevel));
6002
6003 float radius = 5.0f;
6004 int32 duration = m_spellInfo->GetDuration();
6005
6006 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
6007 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
6008
6009 //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
6010 Map* map = caster->GetMap();
6011 TempSummon* summon = nullptr;
6012
6013 uint32 currMinionsCount = m_caster->m_Controlled.size();
6014 uint32 totalNumGuardians = numGuardians + currMinionsCount;
6015
6016 for (uint32 count = 0; count < numGuardians; ++count)
6017 {
6018 Position pos;
6019
6020 // xinef: do not use precalculated position for effect summon pet in this function
6021 // it means it was cast by NPC and should have its position overridden unless the
6022 // target position is specified in the DB AND the effect has no or zero radius
6023 if ((totalNumGuardians == 1 && GetSpellInfo()->Effects[i].Effect != SPELL_EFFECT_SUMMON_PET) ||
6024 (GetSpellInfo()->Effects[i].TargetA.GetTarget() == TARGET_DEST_DB &&
6025 (!GetSpellInfo()->Effects[i].HasRadius() || GetSpellInfo()->Effects[i].RadiusEntry->RadiusMax == 0)))
6026 {
6027 pos = *destTarget;
6028 }
6029 else
6030 {
6031 // randomize position
6032 pos = m_caster->GetRandomPoint(*destTarget, radius);
6033 }
6034
6035 summon = map->SummonCreature(entry, pos, properties, duration, caster, m_spellInfo->Id, 0, personalSpawn);
6036 if (!summon)
6037 return;
6038
6039 // xinef: set calculated level
6040 summon->SetLevel(summonLevel);
6041
6042 // if summonLevel changed, set stats for calculated level
6043 if (summonLevel != caster->GetLevel())
6044 {
6045 ((Guardian*)summon)->InitStatsForLevel(summonLevel);
6046 }
6047
6048 // xinef: if we have more than one guardian, change follow angle
6049 if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && totalNumGuardians > 1)
6050 ((Minion*)summon)->SetFollowAngle(m_caster->GetAbsoluteAngle(pos.GetPositionX(), pos.GetPositionY()));
6051 //else if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && m_targets.HasDst())
6052 // ((Minion*)summon)->SetFollowAngle(m_caster->GetAngle(summon));
6053
6054 // xinef: move this here, some auras are added in initstatsforlevel!
6055 if (!summon->IsInCombat() && !summon->IsTrigger())
6056 {
6057 // summon->AI()->EnterEvadeMode();
6058 summon->GetMotionMaster()->Clear(false);
6060 }
6061
6062 if (properties && properties->Category == SUMMON_CATEGORY_ALLY)
6063 summon->SetFaction(caster->GetFaction());
6064
6066 }
6067
6068 // Summon infernal, cast enslave demon
6069 // xinef: have to do it here because in Pet init stats infernal is not in world, imo this should be changed...
6070 if (summon)
6071 {
6072 switch (m_spellInfo->Id)
6073 {
6074 // Inferno, Warlock summon spell
6075 case 1122:
6076 caster->AddAura(61191, summon);
6077 break;
6078 // Ritual of Doom, Warlock summon spell
6079 case 60478:
6080 caster->AddAura(SPELL_RITUAL_ENSLAVEMENT, summon);
6081 break;
6082 }
6083 }
6084}
@ SPELL_RITUAL_ENSLAVEMENT
Definition: PetDefines.h:155
@ CONFIG_MAX_PLAYER_LEVEL
Definition: IWorld.h:240
@ CONFIG_WORLD_BOSS_LEVEL_DIFF
Definition: IWorld.h:290
@ SKILL_ENGINEERING
Definition: SharedDefines.h:2923
bool IsTrigger() const
Definition: Creature.h:78
Definition: TemporarySummon.h:76
Unit * GetOwner() const
Definition: TemporarySummon.cpp:385
void SetLevel(uint8 lvl, bool showLevelChange=true)
Definition: Unit.cpp:15374

References Unit::AddAura(), SummonPropertiesEntry::Category, MotionMaster::Clear(), CONFIG_MAX_PLAYER_LEVEL, CONFIG_WORLD_BOSS_LEVEL_DIFF, destTarget, ExecuteLogEffectSummonObject(), Position::GetAbsoluteAngle(), SpellInfo::GetDuration(), Unit::GetFaction(), Unit::GetFollowAngle(), Unit::GetLevel(), WorldObject::GetMap(), Unit::GetMotionMaster(), Minion::GetOwner(), Position::GetPositionX(), Position::GetPositionY(), WorldObject::GetRandomPoint(), Player::GetSkillValue(), GetSpellInfo(), Unit::GetSpellModOwner(), Item::GetTemplate(), Object::GetTypeId(), Unit::HasUnitTypeMask(), SpellInfo::Id, Unit::IsInCombat(), Unit::IsTotem(), Creature::IsTrigger(), m_caster, m_CastItem, Unit::m_Controlled, m_originalCaster, m_spellInfo, MOTION_SLOT_ACTIVE, MotionMaster::MoveFollow(), PET_FOLLOW_DIST, Unit::SetFaction(), Unit::SetLevel(), SKILL_ENGINEERING, SPELL_EFFECT_SUMMON_PET, SPELL_RITUAL_ENSLAVEMENT, SPELLMOD_DURATION, SUMMON_CATEGORY_ALLY, Map::SummonCreature(), sWorld, TARGET_DEST_DB, Object::ToPlayer(), Unit::ToTotem(), TYPEID_PLAYER, and UNIT_MASK_MINION.

Referenced by EffectSummonPet(), and EffectSummonType().

◆ TakeAmmo()

void Spell::TakeAmmo ( )
5366{
5368 {
5370
5371 // wands don't have ammo
5372 if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
5373 return;
5374
5375 if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN)
5376 {
5377 if (pItem->GetMaxStackCount() == 1)
5378 {
5379 // decrease durability for non-stackable throw weapon
5381 }
5382 else
5383 {
5384 // decrease items amount for stackable throw weapon
5385 uint32 count = 1;
5386 m_caster->ToPlayer()->DestroyItemCount(pItem, count, true);
5387 }
5388 }
5390 m_caster->ToPlayer()->DestroyItemCount(ammo, 1, true);
5391 }
5392}
@ INVTYPE_THROWN
Definition: ItemTemplate.h:289
@ EQUIPMENT_SLOT_RANGED
Definition: Player.h:692
uint32 GetMaxStackCount() const
Definition: Item.h:271
void DurabilityPointLossForEquipSlot(EquipmentSlots slot)
Definition: Player.cpp:4760

References Player::DestroyItemCount(), Player::DurabilityPointLossForEquipSlot(), EQUIPMENT_SLOT_RANGED, Item::GetMaxStackCount(), Item::GetTemplate(), Object::GetTypeId(), Object::GetUInt32Value(), Player::GetWeaponForAttack(), ItemTemplate::InventoryType, INVTYPE_THROWN, Item::IsBroken(), ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, PLAYER_AMMO_ID, RANGED_ATTACK, ItemTemplate::SubClass, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by handle_immediate(), and HandleLaunchPhase().

◆ TakeCastItem()

void Spell::TakeCastItem ( )
5239{
5241 return;
5242
5243 // not remove cast item at triggered spell (equipping, weapon damage, etc)
5245 return;
5246
5247 ItemTemplate const* proto = m_CastItem->GetTemplate();
5248
5249 if (!proto)
5250 {
5251 // This code is to avoid a crash
5252 // I'm not sure, if this is really an error, but I guess every item needs a prototype
5253 LOG_ERROR("spells", "Cast item has no item prototype {}", m_CastItem->GetGUID().ToString());
5254 return;
5255 }
5256
5257 bool expendable = false;
5258 bool withoutCharges = false;
5259
5260 for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
5261 {
5262 if (proto->Spells[i].SpellId)
5263 {
5264 // item has limited charges
5265 if (proto->Spells[i].SpellCharges)
5266 {
5267 if (proto->Spells[i].SpellCharges < 0)
5268 expendable = true;
5269
5270 int32 charges = m_CastItem->GetSpellCharges(i);
5271
5272 // item has charges left
5273 if (charges)
5274 {
5275 (charges > 0) ? --charges : ++charges; // std::abs(charges) less at 1 after use
5276 if (proto->Stackable == 1)
5277 m_CastItem->SetSpellCharges(i, charges);
5279 }
5280
5281 // all charges used
5282 withoutCharges = (charges == 0);
5283 }
5284 }
5285 }
5286
5287 if (expendable && withoutCharges)
5288 {
5289 uint32 count = 1;
5290 m_caster->ToPlayer()->DestroyItemCount(m_CastItem, count, true);
5291
5292 // prevent crash at access to deleted m_targets.GetItemTarget
5294 m_targets.SetItemTarget(nullptr);
5295
5296 m_CastItem = nullptr;
5298 }
5299}
void SetSpellCharges(uint8 index, int32 value)
Definition: Item.h:315
int32 Stackable
Definition: ItemTemplate.h:653

References ObjectGuid::Clear(), Player::DestroyItemCount(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), Item::GetSpellCharges(), Item::GetTemplate(), Object::GetTypeId(), HasTriggeredCastFlag(), ITEM_CHANGED, LOG_ERROR, m_caster, m_CastItem, m_castItemGUID, m_targets, MAX_ITEM_PROTO_SPELLS, SpellCastTargets::SetItemTarget(), Item::SetSpellCharges(), Item::SetState(), _Spell::SpellCharges, _Spell::SpellId, ItemTemplate::Spells, ItemTemplate::Stackable, Object::ToPlayer(), ObjectGuid::ToString(), TRIGGERED_IGNORE_CAST_ITEM, and TYPEID_PLAYER.

Referenced by _cast(), and handle_immediate().

◆ TakePower()

void Spell::TakePower ( )
5302{
5304 return;
5305
5306 //Don't take power if the spell is cast while .cheat power is enabled.
5309 return;
5310
5312 bool hit = true;
5314 {
5316 if (ObjectGuid targetGUID = m_targets.GetUnitTargetGUID())
5317 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5318 if (ihit->targetGUID == targetGUID)
5319 {
5320 if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_BLOCK && ihit->missCondition != SPELL_MISS_ABSORB && ihit->missCondition != SPELL_MISS_REFLECT)
5321 {
5322 hit = false;
5323 //lower spell cost on fail (by talent aura)
5324 if (Player* modOwner = m_caster->ToPlayer()->GetSpellModOwner())
5325 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost, this);
5326 }
5327 break;
5328 }
5329 }
5330
5331 if (PowerType == POWER_RUNE)
5332 {
5333 TakeRunePower(hit);
5334 return;
5335 }
5336
5337 if (!m_powerCost)
5338 return;
5339
5340 // health as power used
5341 if (PowerType == POWER_HEALTH)
5342 {
5344 return;
5345 }
5346
5347 if (PowerType >= MAX_POWERS)
5348 {
5349 LOG_ERROR("spells", "Spell::TakePower: Unknown power type '{}'", PowerType);
5350 return;
5351 }
5352
5353 if (hit)
5355 else
5357
5358 // Set the five second timer
5359 if (PowerType == POWER_MANA && m_powerCost > 0)
5360 {
5362 }
5363}
@ SPELLMOD_SPELL_COST_REFUND_ON_FAIL
Definition: SpellDefines.h:107
@ SPELL_MISS_ABSORB
Definition: SharedDefines.h:1529
int32 ModifyHealth(int32 val)
Definition: Unit.cpp:14007
void SetLastManaUse(uint32 spellCastTime)
Definition: Unit.h:1559
void TakeRunePower(bool didHit)
Definition: Spell.cpp:5448

References CHEAT_POWER, Player::GetCommandStatus(), GameTime::GetGameTimeMS(), Unit::GetSpellModOwner(), Object::GetTypeId(), SpellCastTargets::GetUnitTargetGUID(), SpellInfo::Id, irand(), LOG_ERROR, m_caster, m_CastItem, m_powerCost, m_spellInfo, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, MAX_POWERS, Unit::ModifyHealth(), Unit::ModifyPower(), POWER_ENERGY, POWER_HEALTH, POWER_MANA, POWER_RAGE, POWER_RUNE, POWER_RUNIC_POWER, SpellInfo::PowerType, Unit::SetLastManaUse(), SPELL_MISS_ABSORB, SPELL_MISS_BLOCK, SPELL_MISS_NONE, SPELL_MISS_REFLECT, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, TakeRunePower(), Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by _cast().

◆ TakeReagents()

void Spell::TakeReagents ( )
5518{
5520 return;
5521
5522 ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : nullptr;
5523
5524 // do not take reagents for these item casts
5525 if (castItemTemplate && castItemTemplate->Flags & ITEM_FLAG_NO_REAGENT_COST)
5526 return;
5527
5528 Player* p_caster = m_caster->ToPlayer();
5529 if (p_caster->CanNoReagentCast(m_spellInfo))
5530 return;
5531
5532 for (uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x)
5533 {
5534 if (m_spellInfo->Reagent[x] <= 0)
5535 continue;
5536
5537 uint32 itemid = m_spellInfo->Reagent[x];
5538 uint32 itemcount = m_spellInfo->ReagentCount[x];
5539
5540 // if CastItem is also spell reagent
5541 if (castItemTemplate && castItemTemplate->ItemId == itemid)
5542 {
5543 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
5544 {
5545 // CastItem will be used up and does not count as reagent
5546 int32 charges = m_CastItem->GetSpellCharges(s);
5547 if (castItemTemplate->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
5548 {
5549 ++itemcount;
5550 break;
5551 }
5552 }
5553
5554 m_CastItem = nullptr;
5556 }
5557
5558 // if GetItemTarget is also spell reagent
5559 if (m_targets.GetItemTargetEntry() == itemid)
5560 m_targets.SetItemTarget(nullptr);
5561
5562 p_caster->DestroyItemCount(itemid, itemcount, true);
5563 }
5564}
uint32 ItemId
Definition: ItemTemplate.h:628

References Player::CanNoReagentCast(), ObjectGuid::Clear(), Player::DestroyItemCount(), ItemTemplate::Flags, SpellCastTargets::GetItemTargetEntry(), Item::GetSpellCharges(), Item::GetTemplate(), Object::GetTypeId(), ITEM_FLAG_NO_REAGENT_COST, ItemTemplate::ItemId, m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, MAX_ITEM_PROTO_SPELLS, MAX_SPELL_REAGENTS, SpellInfo::Reagent, SpellInfo::ReagentCount, SpellCastTargets::SetItemTarget(), _Spell::SpellCharges, ItemTemplate::Spells, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by _cast().

◆ TakeRunePower()

void Spell::TakeRunePower ( bool  didHit)
5449{
5451 return;
5452
5453 SpellRuneCostEntry const* runeCostData = sSpellRuneCostStore.LookupEntry(m_spellInfo->RuneCostID);
5454 if (!runeCostData || (runeCostData->NoRuneCost() && runeCostData->NoRunicPowerGain()))
5455 return;
5456
5457 Player* player = m_caster->ToPlayer();
5458 m_runesState = player->GetRunesState(); // store previous state
5459
5460 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5461
5462 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5463 {
5464 runeCost[i] = runeCostData->RuneCost[i];
5465 if (Player* modOwner = m_caster->GetSpellModOwner())
5466 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5467 }
5468
5469 runeCost[RUNE_DEATH] = 0; // calculated later
5470
5471 for (uint32 i = 0; i < MAX_RUNES; ++i)
5472 {
5473 RuneType rune = player->GetCurrentRune(i);
5474 if (!player->GetRuneCooldown(i) && runeCost[rune] > 0)
5475 {
5476 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5477 player->SetLastUsedRune(rune);
5478 runeCost[rune]--;
5479 }
5480 }
5481
5482 // Xinef: firstly consume death runes of base type
5483 // Xinef: in second loop consume all available
5484 for (uint8 loop = 0; loop < 2; ++loop)
5485 {
5486 runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
5487 if (runeCost[RUNE_DEATH] > 0)
5488 {
5489 for (uint8 i = 0; i < MAX_RUNES; ++i)
5490 {
5491 RuneType rune = player->GetCurrentRune(i);
5492 if (!player->GetRuneCooldown(i) && rune == RUNE_DEATH && (loop ? true : (runeCost[player->GetBaseRune(i)] > 0)))
5493 {
5494 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5495 player->SetLastUsedRune(rune);
5496 runeCost[rune]--;
5497 if (!loop)
5498 runeCost[player->GetBaseRune(i)]--;
5499
5500 // keep Death Rune type if missed
5501 if (didHit)
5502 player->RestoreBaseRune(i);
5503
5504 if (runeCost[RUNE_DEATH] == 0)
5505 break;
5506 }
5507 }
5508 }
5509 }
5510
5511 // you can gain some runic power when use runes
5512 if (didHit)
5513 if (int32 rp = int32(runeCostData->runePowerGain * sWorld->getRate(RATE_POWER_RUNICPOWER_INCOME)))
5514 player->ModifyPower(POWER_RUNIC_POWER, int32(rp));
5515}
@ RUNE_UNHOLY
Definition: Player.h:410
@ RUNE_BLOOD
Definition: Player.h:409
@ RUNE_MISS_COOLDOWN
Definition: Player.h:404
@ RATE_POWER_RUNICPOWER_INCOME
Definition: IWorld.h:435
void SetLastUsedRune(RuneType type)
Definition: Player.h:2489
uint32 GetRuneBaseCooldown(uint8 index, bool skipGrace)
Definition: Player.cpp:13316
void RestoreBaseRune(uint8 index)
Definition: Player.cpp:13345
bool NoRunicPowerGain() const
Definition: DBCStructure.h:1811
uint32 runePowerGain
Definition: DBCStructure.h:1808

References CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, Player::GetBaseRune(), Player::GetCurrentRune(), Player::GetRuneBaseCooldown(), Player::GetRuneCooldown(), Player::GetRunesState(), Unit::GetSpellModOwner(), Object::GetTypeId(), SpellInfo::Id, Unit::IsClass(), m_caster, m_runesState, m_spellInfo, MAX_RUNES, Unit::ModifyPower(), SpellRuneCostEntry::NoRuneCost(), SpellRuneCostEntry::NoRunicPowerGain(), NUM_RUNE_TYPES, POWER_RUNIC_POWER, RATE_POWER_RUNICPOWER_INCOME, Player::RestoreBaseRune(), RUNE_BLOOD, RUNE_DEATH, RUNE_FROST, RUNE_MISS_COOLDOWN, RUNE_UNHOLY, SpellRuneCostEntry::RuneCost, SpellInfo::RuneCostID, SpellRuneCostEntry::runePowerGain, Player::SetLastUsedRune(), Player::SetRuneCooldown(), SPELLMOD_COST, sSpellRuneCostStore, sWorld, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by TakePower().

◆ TriggerGlobalCooldown()

void Spell::TriggerGlobalCooldown ( )
protected
8827{
8829 if (!gcd)
8830 {
8831 // Xinef: fix for charmed pet spells with no cooldown info
8833 gcd = MIN_GCD;
8834 else
8835 return;
8836 }
8837
8840 return;
8841
8842 // Global cooldown can't leave range 1..1.5 secs
8843 // There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns
8844 // but as tests show are not affected by any spell mods.
8846 {
8847 // gcd modifier auras are applied only to own spells and only players have such mods
8850
8851 // Apply haste rating
8854 {
8855 gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
8856 }
8857
8858 if (gcd < MIN_GCD)
8859 gcd = MIN_GCD;
8860 else if (gcd > MAX_GCD)
8861 gcd = MAX_GCD;
8862 }
8863
8864 // Only players or controlled units have global cooldown
8865 if (m_caster->GetCharmInfo())
8867 else if (m_caster->GetTypeId() == TYPEID_PLAYER)
8869}
@ MIN_GCD
Definition: Spell.cpp:8811
@ MAX_GCD
Definition: Spell.cpp:8812
@ SPELLMOD_GLOBAL_COOLDOWN
Definition: SpellDefines.h:98
void AddGlobalCooldown(SpellInfo const *spellInfo, uint32 gcd)
Definition: CharmInfo.cpp:403

References GlobalCooldownMgr::AddGlobalCooldown(), Player::ApplySpellMod(), SpellInfo::CategoryRecoveryTime, CHEAT_COOLDOWN, SpellInfo::DmgClass, Unit::GetCharmInfo(), Player::GetCommandStatus(), Object::GetFloatValue(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), Object::GetTypeId(), SpellInfo::HasAttribute(), SpellInfo::Id, m_caster, m_spellInfo, MAX_GCD, MIN_GCD, SpellInfo::RecoveryTime, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLMOD_GLOBAL_COOLDOWN, SpellInfo::StartRecoveryCategory, SpellInfo::StartRecoveryTime, Object::ToPlayer(), TYPEID_PLAYER, and UNIT_MOD_CAST_SPEED.

Referenced by prepare().

◆ update()

void Spell::update ( uint32  difftime)
4393{
4394 // update pointers based at it's GUIDs
4395 if (!UpdatePointers())
4396 {
4397 // cancel the spell if UpdatePointers() returned false, something wrong happened there
4398 cancel();
4399 return;
4400 }
4401
4403 {
4404 LOG_DEBUG("spells.aura", "Spell {} is cancelled due to removal of target.", m_spellInfo->Id);
4405 cancel();
4406 return;
4407 }
4408
4409 // check if the player caster has moved before the spell finished
4410 // xinef: added preparing state (real cast, skip channels as they have other flags for this)
4411 if ((m_caster->GetTypeId() == TYPEID_PLAYER && m_timer != 0) &&
4414 {
4415 // don't cancel for melee, autorepeat, triggered and instant spells
4417 cancel(true);
4418 }
4419
4420 switch (m_spellState)
4421 {
4423 {
4424 if (m_timer > 0)
4425 {
4426 if (difftime >= (uint32)m_timer)
4427 m_timer = 0;
4428 else
4429 m_timer -= difftime;
4430 }
4431
4432 if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
4433 // don't CheckCast for instant spells - done in spell::prepare, skip duplicate checks, needed for range checks for example
4434 cast(!m_casttime);
4435 break;
4436 }
4438 {
4439 if (m_timer)
4440 {
4441 if (m_timer > 0)
4442 {
4443 if (difftime >= (uint32)m_timer)
4444 m_timer = 0;
4445 else
4446 m_timer -= difftime;
4447 }
4448 }
4449
4450 if (m_timer == 0)
4451 {
4453
4454 finish();
4455 }
4456 // Xinef: Dont update channeled target list on last tick, allow auras to update duration properly
4457 // Xinef: Added this strange check because of diffrent update routines for players / creatures
4458 // Xinef: If creature gets new aura in 800ms and in 840ms its updated with diff 270, not 40 is removed from duration but 270
4459 // Xinef: so the aura can be removed in different updates for all units
4460 else if ((m_timer < 0 || m_timer > 300) && !UpdateChanneledTargetList())
4461 {
4462 LOG_DEBUG("spells.aura", "Channeled spell {} is removed due to lack of targets", m_spellInfo->Id);
4464 finish();
4465 }
4466 break;
4467 }
4468 default:
4469 break;
4470 }
4471}
bool UpdateChanneledTargetList()
Definition: Spell.cpp:3379

References cancel(), cast(), SpellInfo::Effects, finish(), Object::GetTypeId(), SpellCastTargets::GetUnitTarget(), SpellCastTargets::GetUnitTargetGUID(), Unit::HasUnitMovementFlag(), SpellInfo::Id, SpellInfo::InterruptFlags, IsAutoRepeat(), Unit::isMoving(), IsNextMeleeSwingSpell(), IsTriggered(), LOG_DEBUG, m_caster, m_casttime, m_spellInfo, m_spellState, m_targets, m_timer, MOVEMENTFLAG_FALLING_FAR, SendChannelUpdate(), SPELL_EFFECT_STUCK, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_CASTING, SPELL_STATE_PREPARING, TYPEID_PLAYER, UpdateChanneledTargetList(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ UpdateChanneledTargetList()

bool Spell::UpdateChanneledTargetList ( )
protected
3380{
3381 // Not need check return true
3383 return true;
3384
3385 uint8 channelTargetEffectMask = m_channelTargetEffectMask;
3386 uint8 channelAuraMask = 0;
3387 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3389 channelAuraMask |= 1 << i;
3390
3391 channelAuraMask &= channelTargetEffectMask;
3392
3393 float range = 0;
3394 if (channelAuraMask)
3395 {
3397 if (range == 0)
3398 for(int i = EFFECT_0; i <= EFFECT_2; ++i)
3399 if (channelAuraMask & (1 << i) && m_spellInfo->Effects[i].RadiusEntry)
3400 {
3401 range = m_spellInfo->Effects[i].CalcRadius(nullptr, nullptr);
3402 break;
3403 }
3404
3405 if (Player* modOwner = m_caster->GetSpellModOwner())
3406 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
3407
3408 // xinef: add little tolerance level
3409 range += std::min(3.0f, range * 0.1f); // 10% but no more than 3yd
3410 }
3411
3412 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3413 {
3414 if (ihit->missCondition == SPELL_MISS_NONE && (channelTargetEffectMask & ihit->effectMask))
3415 {
3416 Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
3417
3418 if (!unit)
3419 continue;
3420
3421 if (IsValidDeadOrAliveTarget(unit))
3422 {
3423 if (channelAuraMask & ihit->effectMask)
3424 {
3426 {
3427 if (m_caster != unit)
3428 {
3429 if (!m_caster->IsWithinDistInMap(unit, range))
3430 {
3431 ihit->effectMask &= ~aurApp->GetEffectMask();
3432 unit->RemoveAura(aurApp);
3433 continue;
3434 }
3435 // Xinef: Update Orientation server side (non players wont sent appropriate packets)
3438 }
3439 }
3440 else // aura is dispelled
3441 continue;
3442 }
3443
3444 channelTargetEffectMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
3445 }
3446 }
3447 }
3448
3449 // Xinef: not all effects are covered, remove applications from all targets
3450 if (channelTargetEffectMask != 0)
3451 {
3452 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3453 if (ihit->missCondition == SPELL_MISS_NONE && (channelAuraMask & ihit->effectMask))
3454 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3455 if (IsValidDeadOrAliveTarget(unit))
3457 {
3458 ihit->effectMask &= ~aurApp->GetEffectMask();
3459 unit->RemoveAura(aurApp);
3460 }
3461 }
3462
3463 // is all effects from m_needAliveTargetMask have alive targets
3464 return channelTargetEffectMask == 0;
3465}
@ SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL
Definition: SharedDefines.h:433
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
Definition: Object.cpp:1321
AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraApplication *except=nullptr) const
Definition: Unit.cpp:5507
void UpdateOrientation(float orientation)
Only server-side orientation update, does not broadcast to client.
Definition: Unit.cpp:19969
bool IsValidDeadOrAliveTarget(Unit const *target) const
Definition: Spell.cpp:8209

References EFFECT_0, EFFECT_2, SpellInfo::Effects, Position::GetAngle(), Unit::GetAuraApplication(), Object::GetGUID(), SpellInfo::GetMaxRange(), Unit::GetSpellModOwner(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, SpellInfo::IsPositive(), IsValidDeadOrAliveTarget(), WorldObject::IsWithinDistInMap(), m_caster, m_channelTargetEffectMask, m_originalCasterGUID, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::RemoveAura(), SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL, SPELL_EFFECT_APPLY_AURA, SPELL_MISS_NONE, SPELLMOD_RANGE, and Unit::UpdateOrientation().

Referenced by update().

◆ UpdatePointers()

bool Spell::UpdatePointers ( )
7848{
7851 else
7852 {
7855 m_originalCaster = nullptr;
7856 }
7857
7859 {
7861 // cast item not found, somehow the item is no longer where we expected
7862 if (!m_CastItem)
7863 return false;
7864 }
7865 else
7866 m_CastItem = nullptr;
7867
7869
7870 // further actions done only for dest targets
7871 if (!m_targets.HasDst())
7872 return true;
7873
7874 // cache last transport
7875 WorldObject* transport = nullptr;
7876
7877 // update effect destinations (in case of moved transport dest target)
7878 for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
7879 {
7880 SpellDestination& dest = m_destTargets[effIndex];
7881 if (!dest._transportGUID)
7882 continue;
7883
7884 if (!transport || transport->GetGUID() != dest._transportGUID)
7886
7887 if (transport)
7888 {
7889 dest._position.Relocate(transport);
7891 }
7892 }
7893
7894 return true;
7895}
WorldObject * GetWorldObject(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:118
void RelocateOffset(const Position &offset)
Definition: Position.cpp:58
Position _transportOffset
Definition: Spell.h:105
ObjectGuid _transportGUID
Definition: Spell.h:104
void Update(Unit *caster)
Definition: Spell.cpp:479

References SpellDestination::_position, SpellDestination::_transportGUID, SpellDestination::_transportOffset, Object::GetGUID(), Player::GetItemByGuid(), Object::GetTypeId(), ObjectAccessor::GetUnit(), ObjectAccessor::GetWorldObject(), SpellCastTargets::HasDst(), Object::IsInWorld(), m_caster, m_CastItem, m_castItemGUID, m_destTargets, m_originalCaster, m_originalCasterGUID, m_targets, MAX_SPELL_EFFECTS, Position::Relocate(), Position::RelocateOffset(), Object::ToPlayer(), TYPEID_PLAYER, and SpellCastTargets::Update().

Referenced by _cast(), handle_delayed(), and update().

◆ WriteAmmoToPacket()

void Spell::WriteAmmoToPacket ( WorldPacket data)
4915{
4916 uint32 ammoInventoryType = 0;
4917 uint32 ammoDisplayID = 0;
4918
4920 {
4922 if (pItem)
4923 {
4924 ammoInventoryType = pItem->GetTemplate()->InventoryType;
4925 if (ammoInventoryType == INVTYPE_THROWN)
4926 ammoDisplayID = pItem->GetTemplate()->DisplayInfoID;
4927 else
4928 {
4930 if (ammoID)
4931 {
4932 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(ammoID);
4933 if (pProto)
4934 {
4935 ammoDisplayID = pProto->DisplayInfoID;
4936 ammoInventoryType = pProto->InventoryType;
4937 }
4938 }
4939 else if (m_caster->HasAura(46699)) // Requires No Ammo
4940 {
4941 ammoDisplayID = 5996; // normal arrow
4942 ammoInventoryType = INVTYPE_AMMO;
4943 }
4944 }
4945 }
4946 }
4947 else
4948 {
4949 uint32 nonRangedAmmoDisplayID = 0;
4950 uint32 nonRangedAmmoInventoryType = 0;
4951 for (uint8 i = 0; i < 3; ++i)
4952 {
4954 {
4955 if (ItemEntry const* itemEntry = sItemStore.LookupEntry(item_id))
4956 {
4957 if (itemEntry->ClassID == ITEM_CLASS_WEAPON)
4958 {
4959 switch (itemEntry->SubclassID)
4960 {
4962 ammoDisplayID = itemEntry->DisplayInfoID;
4963 ammoInventoryType = itemEntry->InventoryType;
4964 break;
4967 ammoDisplayID = 5996; // is this need fixing?
4968 ammoInventoryType = INVTYPE_AMMO;
4969 break;
4971 ammoDisplayID = 5998; // is this need fixing?
4972 ammoInventoryType = INVTYPE_AMMO;
4973 break;
4974 default:
4975 nonRangedAmmoDisplayID = itemEntry->DisplayInfoID;
4976 nonRangedAmmoInventoryType = itemEntry->InventoryType;
4977 break;
4978 }
4979
4980 if (ammoDisplayID)
4981 break;
4982 }
4983 }
4984 }
4985 }
4986
4987 if (!ammoDisplayID && !ammoInventoryType)
4988 {
4989 ammoDisplayID = nonRangedAmmoDisplayID;
4990 ammoInventoryType = nonRangedAmmoInventoryType;
4991 }
4992 }
4993
4994 *data << uint32(ammoDisplayID);
4995 *data << uint32(ammoInventoryType);
4996}
DBCStorage< ItemEntry > sItemStore(Itemfmt)
@ INVTYPE_AMMO
Definition: ItemTemplate.h:288
@ UNIT_VIRTUAL_ITEM_SLOT_ID
Definition: UpdateFields.h:116
uint32 DisplayInfoID
Definition: ItemTemplate.h:633
Definition: DBCStructure.h:1140

References ItemTemplate::DisplayInfoID, Item::GetTemplate(), Object::GetTypeId(), Object::GetUInt32Value(), Player::GetWeaponForAttack(), Unit::HasAura(), ItemTemplate::InventoryType, INVTYPE_AMMO, INVTYPE_THROWN, ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_BOW, ITEM_SUBCLASS_WEAPON_CROSSBOW, ITEM_SUBCLASS_WEAPON_GUN, ITEM_SUBCLASS_WEAPON_THROWN, m_caster, PLAYER_AMMO_ID, RANGED_ATTACK, sItemStore, sObjectMgr, Object::ToPlayer(), TYPEID_PLAYER, and UNIT_VIRTUAL_ITEM_SLOT_ID.

Referenced by SendSpellGo(), and SendSpellStart().

◆ WriteCastResultInfo()

void Spell::WriteCastResultInfo ( WorldPacket data,
Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError 
)
static
4551{
4552 data << uint8(castCount); // single cast or multi 2.3 (0/1)
4553 data << uint32(spellInfo->Id);
4554 data << uint8(result); // problem
4555 switch (result)
4556 {
4558 data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id
4559 break;
4560 case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id
4561 // hardcode areas limitation case
4562 switch (spellInfo->Id)
4563 {
4564 case 41617: // Cenarion Mana Salve
4565 case 41619: // Cenarion Healing Salve
4566 data << uint32(3905);
4567 break;
4568 case 41618: // Bottled Nethergon Energy
4569 case 41620: // Bottled Nethergon Vapor
4570 data << uint32(3842);
4571 break;
4572 case 45373: // Bloodberry Elixir
4573 data << uint32(4075);
4574 break;
4575 default: // default case (don't must be)
4576 data << uint32(0);
4577 break;
4578 }
4579 break;
4581 if (spellInfo->Totem[0])
4582 data << uint32(spellInfo->Totem[0]);
4583 if (spellInfo->Totem[1])
4584 data << uint32(spellInfo->Totem[1]);
4585 break;
4587 if (spellInfo->TotemCategory[0])
4588 data << uint32(spellInfo->TotemCategory[0]);
4589 if (spellInfo->TotemCategory[1])
4590 data << uint32(spellInfo->TotemCategory[1]);
4591 break;
4595 data << uint32(spellInfo->EquippedItemClass);
4596 data << uint32(spellInfo->EquippedItemSubClassMask);
4597 break;
4599 {
4600 uint32 item = 0;
4601 for (int8 eff = 0; eff < MAX_SPELL_EFFECTS; eff++)
4602 if (spellInfo->Effects[eff].ItemType)
4603 item = spellInfo->Effects[eff].ItemType;
4604 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
4605 if (proto && proto->ItemLimitCategory)
4606 data << uint32(proto->ItemLimitCategory);
4607 break;
4608 }
4610 data << uint32(customError);
4611 break;
4613 {
4614 uint32 missingItem = 0;
4615 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
4616 {
4617 if (spellInfo->Reagent[i] <= 0)
4618 continue;
4619
4620 uint32 itemid = spellInfo->Reagent[i];
4621 uint32 itemcount = spellInfo->ReagentCount[i];
4622
4623 if (!caster->HasItemCount(itemid, itemcount))
4624 {
4625 missingItem = itemid;
4626 break;
4627 }
4628 }
4629
4630 data << uint32(missingItem); // first missing item
4631 break;
4632 }
4634 data << uint32(spellInfo->Mechanic);
4635 break;
4637 data << uint32(spellInfo->EquippedItemSubClassMask);
4638 break;
4640 data << uint32(0); // Item entry
4641 data << uint32(0); // Count
4642 break;
4644 data << uint32(0); // SkillLine.dbc Id
4645 data << uint32(0); // Amount
4646 break;
4648 data << uint32(0); // Skill level
4649 break;
4650 default:
4651 break;
4652 }
4653}
@ SPELL_FAILED_NEED_EXOTIC_AMMO
Definition: SharedDefines.h:1003
@ SPELL_FAILED_FISHING_TOO_LOW
Definition: SharedDefines.h:1130
@ SPELL_FAILED_MIN_SKILL
Definition: SharedDefines.h:1099
@ SPELL_FAILED_PREVENTED_BY_MECHANIC
Definition: SharedDefines.h:1096
@ SPELL_FAILED_REQUIRES_AREA
Definition: SharedDefines.h:1050

References SpellInfo::Effects, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Player::HasItemCount(), SpellInfo::Id, ItemTemplate::ItemLimitCategory, MAX_SPELL_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::Mechanic, SpellInfo::Reagent, SpellInfo::ReagentCount, SpellInfo::RequiresSpellFocus, sObjectMgr, SPELL_FAILED_CUSTOM_ERROR, SPELL_FAILED_EQUIPPED_ITEM_CLASS, SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND, SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND, SPELL_FAILED_FISHING_TOO_LOW, SPELL_FAILED_MIN_SKILL, SPELL_FAILED_NEED_EXOTIC_AMMO, SPELL_FAILED_NEED_MORE_ITEMS, SPELL_FAILED_PREVENTED_BY_MECHANIC, SPELL_FAILED_REAGENTS, SPELL_FAILED_REQUIRES_AREA, SPELL_FAILED_REQUIRES_SPELL_FOCUS, SPELL_FAILED_TOO_MANY_OF_ITEM, SPELL_FAILED_TOTEM_CATEGORY, SPELL_FAILED_TOTEMS, SpellInfo::Totem, and SpellInfo::TotemCategory.

Referenced by SendCastResult(), and SendPetCastResult().

◆ WriteSpellGoTargets()

void Spell::WriteSpellGoTargets ( WorldPacket data)

Writes miss and hit targets for a SMSG_SPELL_GO packet.

5000{
5001 // This function also fill data for channeled spells:
5002 // m_needAliveTargetMask req for stop channelig if one target die
5003 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5004 {
5005 if ((*ihit).effectMask == 0) // No effect apply - all immuned add state
5006 // possibly SPELL_MISS_IMMUNE2 for this??
5007 ihit->missCondition = SPELL_MISS_IMMUNE2;
5008 }
5009
5010 // Hit and miss target counts are both uint8, that limits us to 255 targets for each
5011 // sending more than 255 targets crashes the client (since count sent would be wrong)
5012 // Spells like 40647 (with a huge radius) can easily reach this limit (spell might need
5013 // target conditions but we still need to limit the number of targets sent and keeping
5014 // correct count for both hit and miss).
5015
5016 uint32 hit = 0;
5017 std::size_t hitPos = data->wpos();
5018 *data << (uint8)0; // placeholder
5019 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && hit < 255; ++ihit)
5020 {
5021 if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
5022 {
5023 *data << ihit->targetGUID;
5024 // Xinef: No channeled spell checked, no anything
5025 //m_channelTargetEffectMask |=ihit->effectMask;
5026 ++hit;
5027 }
5028 }
5029
5030 for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end() && hit < 255; ++ighit)
5031 {
5032 *data << ighit->targetGUID; // Always hits
5033 ++hit;
5034 }
5035
5036 uint32 miss = 0;
5037 std::size_t missPos = data->wpos();
5038 *data << (uint8)0; // placeholder
5039 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && miss < 255; ++ihit)
5040 {
5041 if (ihit->missCondition != SPELL_MISS_NONE) // Add only miss
5042 {
5043 *data << ihit->targetGUID;
5044 *data << uint8(ihit->missCondition);
5045 if (ihit->missCondition == SPELL_MISS_REFLECT)
5046 *data << uint8(ihit->reflectResult);
5047 ++miss;
5048 }
5049 }
5050 // Reset m_needAliveTargetMask for non channeled spell
5051 // Xinef: Why do we reset something that is not set??????
5052 //if (!m_spellInfo->IsChanneled())
5053 // m_channelTargetEffectMask = 0;
5054
5055 data->put<uint8>(hitPos, (uint8)hit);
5056 data->put<uint8>(missPos, (uint8)miss);
5057}
std::size_t wpos() const
Definition: ByteBuffer.h:330
void put(std::size_t pos, T value)
Definition: ByteBuffer.h:137

References m_UniqueGOTargetInfo, m_UniqueTargetInfo, ByteBuffer::put(), SPELL_MISS_IMMUNE2, SPELL_MISS_NONE, SPELL_MISS_REFLECT, and ByteBuffer::wpos().

Referenced by SendSpellGo().

Friends And Related Function Documentation

◆ SpellScript

friend class SpellScript
friend

◆ Unit::SetCurrentCastedSpell

void Unit::SetCurrentCastedSpell ( Spell pSpell)
friend

Member Data Documentation

◆ _scriptsLoaded

bool Spell::_scriptsLoaded
protected

Referenced by LoadScripts(), and Spell().

◆ _spellEvent

SpellEvent* Spell::_spellEvent
protected

◆ _spellTargetsSelected

bool Spell::_spellTargetsSelected
protected

Referenced by _cast(), prepare(), and Spell().

◆ _triggeredCastFlags

TriggerCastFlags Spell::_triggeredCastFlags
protected

◆ damage

◆ destTarget

◆ effectHandleMode

SpellEffectHandleMode Spell::effectHandleMode
protected

Referenced by EffectActivateObject(), EffectActivateRune(), EffectActivateSpec(), EffectAddComboPoints(), EffectAddExtraAttacks(), EffectAddFarsight(), EffectAddHonor(), EffectApplyAreaAura(), EffectApplyAura(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectCharge(), EffectChargeDest(), EffectCreateItem(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDestroyAllTotems(), EffectDiscoverTaxi(), EffectDisEnchant(), EffectDismissPet(), EffectDispel(), EffectDispelMechanic(), EffectDistract(), EffectDualWield(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectDamage(), EffectGameObjectRepair(), EffectGameObjectSetDestructionState(), EffectHeal(), EffectHealMaxHealth(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInebriate(), EffectInstaKill(), EffectInterruptCast(), EffectJump(), EffectJumpDest(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectMilling(), EffectModifyThreatPercent(), EffectOpenLock(), EffectParry(), EffectPersistentAA(), EffectPickPocket(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectRemoveAura(), EffectRenamePet(), EffectReputation(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSendTaxi(), EffectSkill(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectSpecCount(), EffectSpiritHeal(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTradeSkill(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), HandleEffects(), and Spell().

◆ focusObject

◆ gameObjTarget

◆ itemTarget

◆ m_appliedMods

◆ m_applyMultiplierMask

uint8 Spell::m_applyMultiplierMask
protected

◆ m_attackType

◆ m_auraScaleMask

uint8 Spell::m_auraScaleMask
protected

◆ m_autoRepeat

bool Spell::m_autoRepeat
protected

◆ m_canReflect

bool Spell::m_canReflect
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_cast_count

◆ m_caster

Unit* const Spell::m_caster
protected

Referenced by _cast(), _handle_finish_phase(), AddGOTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateSpellDamage(), cancel(), CancelGlobalCooldown(), CanOpenLock(), cast(), CheckCast(), CheckCasterAuras(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckSpellFocus(), CheckSrc(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectCharge(), EffectChargeDest(), EffectDestroyAllTotems(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectRepair(), EffectHeal(), EffectHealMaxHealth(), EffectHealthLeech(), EffectInstaKill(), EffectJump(), EffectJumpDest(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnSpell(), EffectMilling(), EffectModifyThreatPercent(), EffectOpenLock(), EffectParry(), EffectPersistentAA(), EffectPickPocket(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTradeSkill(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), finish(), GetCaster(), handle_delayed(), handle_immediate(), HandleLaunchPhase(), HandleThreatSpells(), HasGlobalCooldown(), InitExplicitTargets(), IsChannelActive(), OnSpellLaunch(), prepare(), prepareDataForTriggerSystem(), PrepareTriggersExecutedOnHit(), RecalculateDelayMomentForDst(), SearchAreaTargets(), SearchChainTargets(), SearchNearbyTarget(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTrajTargets(), SendCastResult(), SendChannelStart(), SendChannelUpdate(), SendInterrupted(), SendLogExecute(), SendLoot(), SendPetCastResult(), SendResurrectRequest(), SendSpellCooldown(), SendSpellGo(), SendSpellStart(), Spell(), SummonGuardian(), TakeAmmo(), TakeCastItem(), TakePower(), TakeReagents(), TakeRunePower(), TriggerGlobalCooldown(), update(), UpdateChanneledTargetList(), UpdatePointers(), and WriteAmmoToPacket().

◆ m_CastItem

◆ m_castItemGUID

◆ m_casttime

◆ m_channeledDuration

int32 Spell::m_channeledDuration
protected

◆ m_channelTargetEffectMask

uint8 Spell::m_channelTargetEffectMask
protected

◆ m_comboPointGain

int8 Spell::m_comboPointGain

◆ m_comboTarget

Unit* Spell::m_comboTarget

◆ m_customError

◆ m_damage

◆ m_damageMultipliers

float Spell::m_damageMultipliers[3]
protected

◆ m_delayAtDamageCount

uint8 Spell::m_delayAtDamageCount
protected

Referenced by isDelayableNoMore(), and Spell().

◆ m_delayMoment

◆ m_delayStart

uint64 Spell::m_delayStart
protected

Referenced by GetDelayStart(), SetDelayStart(), and Spell().

◆ m_delayTrajectory

uint64 Spell::m_delayTrajectory
protected

◆ m_destTargets

SpellDestination Spell::m_destTargets[MAX_SPELL_EFFECTS]
protected

◆ m_diminishGroup

DiminishingGroup Spell::m_diminishGroup
protected

◆ m_diminishLevel

DiminishingLevels Spell::m_diminishLevel
protected

◆ m_effectExecuteData

◆ m_executedCurrently

bool Spell::m_executedCurrently
protected

◆ m_glyphIndex

uint32 Spell::m_glyphIndex

◆ m_healing

◆ m_hitTriggerSpells

HitTriggerSpellList Spell::m_hitTriggerSpells
protected

◆ m_immediateHandled

bool Spell::m_immediateHandled
protected

Referenced by _cast(), handle_delayed(), and Spell().

◆ m_loadedScripts

◆ m_needComboPoints

bool Spell::m_needComboPoints
protected

◆ m_originalCaster

◆ m_originalCasterGUID

◆ m_powerCost

◆ m_preCastSpell

uint32 Spell::m_preCastSpell

◆ m_preGeneratedPath

std::unique_ptr<PathGenerator> Spell::m_preGeneratedPath
protected

Referenced by CheckCast(), and EffectCharge().

◆ m_procAttacker

uint32 Spell::m_procAttacker
protected

◆ m_procEx

uint32 Spell::m_procEx
protected

◆ m_procVictim

uint32 Spell::m_procVictim
protected

◆ m_referencedFromCurrentSpell

bool Spell::m_referencedFromCurrentSpell
protected

◆ m_runesState

uint8 Spell::m_runesState
protected

◆ m_selfContainer

Spell** Spell::m_selfContainer
protected

◆ m_skipCheck

bool Spell::m_skipCheck
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_spellAura

◆ m_spellFlags

◆ m_spellInfo

SpellInfo const* const Spell::m_spellInfo

Referenced by _cast(), _handle_finish_phase(), _handle_immediate_phase(), Unit::_UpdateAutoRepeatSpell(), AddGOTarget(), AddItemTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateJumpSpeeds(), CalculateSpellDamage(), CallScriptDestinationTargetSelectHandlers(), CallScriptEffectHandlers(), CallScriptObjectAreaTargetSelectHandlers(), CallScriptObjectTargetSelectHandlers(), CanAutoCast(), cancel(), CancelGlobalCooldown(), CanExecuteTriggersOnHit(), CanOpenLock(), CheckCast(), CheckCasterAuras(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckScriptEffectImplicitTargets(), CheckSpellFocus(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectAddHonor(), EffectApplyGlyph(), EffectBind(), EffectCastButtons(), EffectCharge(), EffectCreateItem(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDiscoverTaxi(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectSetDestructionState(), EffectHeal(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInstaKill(), EffectInterruptCast(), EffectJumpDest(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectOpenLock(), EffectPersistentAA(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRemoveAura(), EffectReputation(), EffectResurrectNew(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSendTaxi(), EffectStealBeneficialBuff(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectWeaponDmg(), finish(), GetCurrentContainer(), GetSearcherTypeMask(), GetSpellInfo(), handle_immediate(), WorldSession::HandleCastSpellOpcode(), HandleEffects(), HandleLaunchPhase(), WorldSession::HandlePetCastSpellOpcode(), HandleThreatSpells(), WorldSession::HandleUpdateMissileTrajectory(), HasGlobalCooldown(), InitExplicitTargets(), IsAutoActionResetSpell(), IsNeedSendToClient(), IsNextMeleeSwingSpell(), IsValidDeadOrAliveTarget(), LoadScripts(), OnSpellLaunch(), prepare(), prepareDataForTriggerSystem(), PrepareTriggersExecutedOnHit(), Player::RemoveSpellMods(), Player::RestoreSpellMods(), SearchAreaTargets(), SearchChainTargets(), SearchNearbyTarget(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTrajTargets(), SelectSpellTargets(), SendCastResult(), SendChannelStart(), SendInterrupted(), SendLogExecute(), SendPetCastResult(), SendResurrectRequest(), SendSpellCooldown(), SendSpellGo(), SendSpellStart(), Unit::SetCurrentCastedSpell(), Player::SetSpellModTakingSpell(), SetSpellValue(), Spell(), SummonGuardian(), TakePower(), TakeReagents(), TakeRunePower(), TriggerGlobalCooldown(), update(), PetAI::UpdateAI(), UpdateChanneledTargetList(), Player::UpdatePotionCooldown(), ~Spell(), and SpellEvent::~SpellEvent().

◆ m_spellSchoolMask

◆ m_spellState

uint32 Spell::m_spellState
protected

◆ m_spellValue

◆ m_targets

SpellCastTargets Spell::m_targets

Referenced by _cast(), CalculateDelayMomentForDst(), CheckCast(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckRange(), CheckSrc(), Unit::DealDamage(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), EffectBind(), EffectChargeDest(), EffectEnchantItemPerm(), EffectJumpDest(), EffectKnockBack(), EffectLeap(), EffectPullTowards(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerSpell(), SpellScript::GetExplTargetDest(), SpellScript::GetExplTargetGObj(), SpellScript::GetExplTargetItem(), SpellScript::GetExplTargetUnit(), SpellScript::GetExplTargetWorldObject(), handle_delayed(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), spell_vehicle_throw_passenger::HandleScript(), WorldSession::HandleUpdateMissileTrajectory(), WorldSession::HandleUpdateProjectilePosition(), InitExplicitTargets(), spell_ioc_launch::Launch(), OnSpellLaunch(), prepare(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitChannelTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTargetObjectTargets(), SelectImplicitTrajTargets(), SelectSpellTargets(), SendChannelStart(), SendSpellGo(), SendSpellStart(), SpellScript::SetExplTargetDest(), TakeCastItem(), TakePower(), TakeReagents(), update(), and UpdatePointers().

◆ m_timer

◆ m_triggeredByAuraSpell

◆ m_UniqueGOTargetInfo

◆ m_UniqueItemInfo

◆ m_UniqueTargetInfo

◆ m_weaponItem

Item* Spell::m_weaponItem

◆ unitTarget

Unit* Spell::unitTarget
protected

Referenced by CheckCast(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), EffectActivateSpec(), EffectAddComboPoints(), EffectAddExtraAttacks(), EffectAddHonor(), EffectApplyAreaAura(), EffectApplyAura(), EffectBind(), EffectCharge(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDiscoverTaxi(), EffectDismissPet(), EffectDispel(), EffectDispelMechanic(), EffectDistract(), EffectDualWield(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectForceCast(), EffectHeal(), EffectHealMaxHealth(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInebriate(), EffectInstaKill(), EffectInterruptCast(), EffectJump(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectModifyThreatPercent(), EffectPickPocket(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectRemoveAura(), EffectRenamePet(), EffectReputation(), EffectResurrect(), EffectResurrectNew(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSendEvent(), EffectSendTaxi(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectSpecCount(), EffectStealBeneficialBuff(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTriggerMissileSpell(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), SpellScript::GetHitCreature(), SpellScript::GetHitPlayer(), SpellScript::GetHitUnit(), HandleEffects(), SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitChainTargets(), SelectImplicitTrajTargets(), and Spell().